diff --git a/cpp_package/src/board_shim.cpp b/cpp_package/src/board_shim.cpp index 3ec1fc74c..b1f37f1da 100644 --- a/cpp_package/src/board_shim.cpp +++ b/cpp_package/src/board_shim.cpp @@ -235,7 +235,8 @@ std::string BoardShim::config_board (std::string config) int response_len = 0; char response[8192]; int res = ::config_board ( - config.c_str (), response, &response_len, board_id, serialized_params.c_str ()); + config.c_str (), response, &response_len, sizeof (response), board_id, + serialized_params.c_str ()); if (res != (int)BrainFlowExitCodes::STATUS_OK) { throw BrainFlowException ("failed to config board", res); @@ -281,6 +282,18 @@ int BoardShim::get_board_id () return master_board_id; } +int BoardShim::get_board_sampling_rate (int preset) +{ + int sampling_rate = -1; + int res = + ::get_board_sampling_rate (preset, &sampling_rate, board_id, serialized_params.c_str ()); + if (res != (int)BrainFlowExitCodes::STATUS_OK) + { + throw BrainFlowException ("failed to get board sampling rate", res); + } + return sampling_rate; +} + ////////////////////////////////////////// ///////////// data desc methods ////////// ////////////////////////////////////////// @@ -289,7 +302,8 @@ json BoardShim::get_board_descr (int board_id, int preset) { char board_descr_str[16000]; int string_len = 0; - int res = ::get_board_descr (board_id, preset, board_descr_str, &string_len); + int res = + ::get_board_descr (board_id, preset, board_descr_str, &string_len, sizeof (board_descr_str)); if (res != (int)BrainFlowExitCodes::STATUS_OK) { throw BrainFlowException ("failed to get board info", res); @@ -368,7 +382,7 @@ std::vector BoardShim::get_eeg_names (int board_id, int preset) { char eeg_names[4096]; int string_len = 0; - int res = ::get_eeg_names (board_id, preset, eeg_names, &string_len); + int res = ::get_eeg_names (board_id, preset, eeg_names, &string_len, sizeof (eeg_names)); if (res != (int)BrainFlowExitCodes::STATUS_OK) { throw BrainFlowException ("failed to get board info", res); @@ -401,7 +415,7 @@ std::string BoardShim::get_device_name (int board_id, int preset) { char name[4096]; int string_len = 0; - int res = ::get_device_name (board_id, preset, name, &string_len); + int res = ::get_device_name (board_id, preset, name, &string_len, sizeof (name)); if (res != (int)BrainFlowExitCodes::STATUS_OK) { throw BrainFlowException ("failed to get board info", res); @@ -602,4 +616,4 @@ std::string BoardShim::get_version () std::string verion_str (version, string_len); return verion_str; -} \ No newline at end of file +} diff --git a/cpp_package/src/inc/board_shim.h b/cpp_package/src/inc/board_shim.h index d5c2f0881..57c4a834c 100644 --- a/cpp_package/src/inc/board_shim.h +++ b/cpp_package/src/inc/board_shim.h @@ -255,6 +255,8 @@ class BoardShim int num_samples, int preset = (int)BrainFlowPresets::DEFAULT_PRESET); /// Get board id, for some boards can be different than provided (playback, streaming) int get_board_id (); + /// get actual sampling rate for prepared board session + int get_board_sampling_rate (int preset = (int)BrainFlowPresets::DEFAULT_PRESET); /// get number of packages in ringbuffer int get_board_data_count (int preset = (int)BrainFlowPresets::DEFAULT_PRESET); /// get all collected data and flush it from internal buffer diff --git a/csharp_package/brainflow/brainflow/board_controller_library.cs b/csharp_package/brainflow/brainflow/board_controller_library.cs index c363db037..a22c974fd 100644 --- a/csharp_package/brainflow/brainflow/board_controller_library.cs +++ b/csharp_package/brainflow/brainflow/board_controller_library.cs @@ -151,7 +151,7 @@ public static class BoardControllerLibrary64 [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int log_message_board_controller (int log_level, string message); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int config_board (string config, byte[] response, int[] len, int board_id, string input_json); + public static extern int config_board (string config, byte[] response, int[] len, int max_len, int board_id, string input_json); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int config_board_with_bytes (byte[] bytes, int len, int board_id, string input_json); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] @@ -159,6 +159,8 @@ public static class BoardControllerLibrary64 [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_sampling_rate (int board_id, int preset, int[] sampling_rate); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_board_sampling_rate (int preset, int[] sampling_rate, int board_id, string input_json); + [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_timestamp_channel (int board_id, int preset, int[] timestamp_channel); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_marker_channel (int board_id, int preset, int[] marker_channel); @@ -195,7 +197,7 @@ public static class BoardControllerLibrary64 [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int is_prepared (int[] prepared, int board_id, string input_json); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int get_eeg_names (int board_id, int preset, byte[] eeg_names, int[] len); + public static extern int get_eeg_names (int board_id, int preset, byte[] eeg_names, int[] len, int max_len); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_resistance_channels (int board_id, int preset, int[] channels, int[] len); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] @@ -203,11 +205,11 @@ public static class BoardControllerLibrary64 [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_exg_channels (int board_id, int preset, int[] channels, int[] len); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int get_device_name (int board_id, int preset, byte[] name, int[] len); + public static extern int get_device_name (int board_id, int preset, byte[] name, int[] len, int max_len); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int insert_marker (double value, int preset, int board_id, string input_json); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int get_board_descr (int board_id, int preset, byte[] board_descr, int[] len); + public static extern int get_board_descr (int board_id, int preset, byte[] board_descr, int[] len, int max_len); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int release_all_sessions (); [DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] @@ -241,7 +243,7 @@ public static class BoardControllerLibrary32 [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int log_message_board_controller (int log_level, string message); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int config_board (string config, byte[] response, int[] len, int board_id, string input_json); + public static extern int config_board (string config, byte[] response, int[] len, int max_len, int board_id, string input_json); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int config_board_with_bytes (byte[] bytes, int len, int board_id, string input_json); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] @@ -249,6 +251,8 @@ public static class BoardControllerLibrary32 [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_sampling_rate (int board_id, int preset, int[] sampling_rate); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_board_sampling_rate (int preset, int[] sampling_rate, int board_id, string input_json); + [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_timestamp_channel (int board_id, int preset, int[] timestamp_channel); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_marker_channel (int board_id, int preset, int[] marker_channel); @@ -285,17 +289,17 @@ public static class BoardControllerLibrary32 [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int is_prepared (int[] prepared, int board_id, string input_json); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int get_eeg_names (int board_id, int preset, byte[] eeg_names, int[] len); + public static extern int get_eeg_names (int board_id, int preset, byte[] eeg_names, int[] len, int max_len); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_resistance_channels (int board_id, int preset, int[] channels, int[] len); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int get_exg_channels (int board_id, int preset, int[] channels, int[] len); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int get_device_name (int board_id, int preset, byte[] name, int[] len); + public static extern int get_device_name (int board_id, int preset, byte[] name, int[] len, int max_len); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int insert_marker (double value, int preset, int board_id, string input_json); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] - public static extern int get_board_descr (int board_id, int preset, byte[] board_descr, int[] len); + public static extern int get_board_descr (int board_id, int preset, byte[] board_descr, int[] len, int max_len); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static extern int release_all_sessions (); [DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] @@ -457,14 +461,14 @@ public static int insert_marker (double value, int preset, int board_id, string } - public static int config_board (string config, byte[] str, int[] len, int board_id, string input_json) + public static int config_board (string config, byte[] str, int[] len, int max_len, int board_id, string input_json) { switch (PlatformHelper.get_library_environment ()) { case LibraryEnvironment.x64: - return BoardControllerLibrary64.config_board (config, str, len, board_id, input_json); + return BoardControllerLibrary64.config_board (config, str, len, max_len, board_id, input_json); case LibraryEnvironment.x86: - return BoardControllerLibrary32.config_board (config, str, len, board_id, input_json); + return BoardControllerLibrary32.config_board (config, str, len, max_len, board_id, input_json); } return (int)BrainFlowExitCodes.GENERAL_ERROR; @@ -535,6 +539,19 @@ public static int get_sampling_rate (int board_id, int preset, int[] sampling_ra return (int)BrainFlowExitCodes.GENERAL_ERROR; } + public static int get_board_sampling_rate (int preset, int[] sampling_rate, int board_id, string input_json) + { + switch (PlatformHelper.get_library_environment ()) + { + case LibraryEnvironment.x64: + return BoardControllerLibrary64.get_board_sampling_rate (preset, sampling_rate, board_id, input_json); + case LibraryEnvironment.x86: + return BoardControllerLibrary32.get_board_sampling_rate (preset, sampling_rate, board_id, input_json); + } + + return (int)BrainFlowExitCodes.GENERAL_ERROR; + } + public static int get_package_num_channel (int board_id, int preset, int[] package_num) { switch (PlatformHelper.get_library_environment ()) @@ -600,14 +617,14 @@ public static int get_marker_channel (int board_id, int preset, int[] marker_cha return (int)BrainFlowExitCodes.GENERAL_ERROR; } - public static int get_eeg_names (int board_id, int preset, byte[] names, int[] len) + public static int get_eeg_names (int board_id, int preset, byte[] names, int[] len, int max_len) { switch (PlatformHelper.get_library_environment ()) { case LibraryEnvironment.x64: - return BoardControllerLibrary64.get_eeg_names (board_id, preset, names, len); + return BoardControllerLibrary64.get_eeg_names (board_id, preset, names, len, max_len); case LibraryEnvironment.x86: - return BoardControllerLibrary32.get_eeg_names (board_id, preset, names, len); + return BoardControllerLibrary32.get_eeg_names (board_id, preset, names, len, max_len); } return (int)BrainFlowExitCodes.GENERAL_ERROR; @@ -626,27 +643,27 @@ public static int get_board_presets (int board_id, int[] names, int[] len) return (int)BrainFlowExitCodes.GENERAL_ERROR; } - public static int get_board_descr (int board_id, int preset, byte[] descr, int[] len) + public static int get_board_descr (int board_id, int preset, byte[] descr, int[] len, int max_len) { switch (PlatformHelper.get_library_environment ()) { case LibraryEnvironment.x64: - return BoardControllerLibrary64.get_board_descr (board_id, preset, descr, len); + return BoardControllerLibrary64.get_board_descr (board_id, preset, descr, len, max_len); case LibraryEnvironment.x86: - return BoardControllerLibrary32.get_board_descr (board_id, preset, descr, len); + return BoardControllerLibrary32.get_board_descr (board_id, preset, descr, len, max_len); } return (int)BrainFlowExitCodes.GENERAL_ERROR; } - public static int get_device_name (int board_id, int preset, byte[] name, int[] len) + public static int get_device_name (int board_id, int preset, byte[] name, int[] len, int max_len) { switch (PlatformHelper.get_library_environment ()) { case LibraryEnvironment.x64: - return BoardControllerLibrary64.get_device_name (board_id, preset, name, len); + return BoardControllerLibrary64.get_device_name (board_id, preset, name, len, max_len); case LibraryEnvironment.x86: - return BoardControllerLibrary32.get_device_name (board_id, preset, name, len); + return BoardControllerLibrary32.get_device_name (board_id, preset, name, len, max_len); } return (int)BrainFlowExitCodes.GENERAL_ERROR; diff --git a/csharp_package/brainflow/brainflow/board_shim.cs b/csharp_package/brainflow/brainflow/board_shim.cs index 24211f8f3..17149bab1 100644 --- a/csharp_package/brainflow/brainflow/board_shim.cs +++ b/csharp_package/brainflow/brainflow/board_shim.cs @@ -179,7 +179,7 @@ public static string[] get_eeg_names (int board_id, int preset = (int)BrainFlowP { int[] len = new int[1]; byte[] str = new byte[4096]; - int res = BoardControllerLibrary.get_eeg_names (board_id, preset, str, len); + int res = BoardControllerLibrary.get_eeg_names (board_id, preset, str, len, str.Length); if (res != (int)BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res); @@ -222,7 +222,7 @@ public static T get_board_descr (int board_id, int preset = (int)BrainFlowPre { int[] len = new int[1]; byte[] str = new byte[16000]; - int res = BoardControllerLibrary.get_board_descr (board_id, preset, str, len); + int res = BoardControllerLibrary.get_board_descr (board_id, preset, str, len, str.Length); if (res != (int)BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res); @@ -246,7 +246,7 @@ public static string get_device_name (int board_id, int preset = (int)BrainFlowP { int[] len = new int[1]; byte[] str = new byte[4096]; - int res = BoardControllerLibrary.get_device_name (board_id, preset, str, len); + int res = BoardControllerLibrary.get_device_name (board_id, preset, str, len, str.Length); if (res != (int)BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res); @@ -717,7 +717,7 @@ public string config_board (string config) { int[] len = new int[1]; byte[] str = new byte[4096]; - int res = BoardControllerLibrary.config_board (config, str, len, board_id, input_json); + int res = BoardControllerLibrary.config_board (config, str, len, str.Length, board_id, input_json); if (res != (int)BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res); @@ -839,6 +839,22 @@ public int get_board_id () return master_board; } + /// + /// get actual sampling rate for this prepared board session + /// + /// preset for device + /// sampling rate + public int get_board_sampling_rate (int preset = (int)BrainFlowPresets.DEFAULT_PRESET) + { + int[] val = new int[1]; + int res = BoardControllerLibrary.get_board_sampling_rate (preset, val, board_id, input_json); + if (res != (int)BrainFlowExitCodes.STATUS_OK) + { + throw new BrainFlowError (res); + } + return val[0]; + } + /// /// Get input params /// diff --git a/java_package/brainflow/src/main/java/brainflow/BoardShim.java b/java_package/brainflow/src/main/java/brainflow/BoardShim.java index 7603178ae..0c9bbcc23 100644 --- a/java_package/brainflow/src/main/java/brainflow/BoardShim.java +++ b/java_package/brainflow/src/main/java/brainflow/BoardShim.java @@ -23,7 +23,8 @@ private interface DllInterface extends Library { int prepare_session (int board_id, String params); - int config_board (String config, byte[] names, int[] len, int board_id, String params); + int config_board ( + String config, byte[] names, int[] len, int max_len, int board_id, String params); int config_board_with_bytes (byte[] bytes, int len, int board_id, String params); @@ -55,6 +56,7 @@ int get_current_board_data (int num_samples, int preset, double[] data_buf, int[ int java_set_jnienv (JNIEnv java_jnienv); int get_sampling_rate (int board_id, int preset, int[] sampling_rate); + int get_board_sampling_rate (int preset, int[] sampling_rate, int board_id, String params); int get_battery_channel (int board_id, int preset, int[] battery_channel); @@ -100,11 +102,11 @@ int get_current_board_data (int num_samples, int preset, double[] data_buf, int[ int is_prepared (int[] prepared, int board_id, String params); - int get_eeg_names (int board_id, int preset, byte[] names, int[] len); + int get_eeg_names (int board_id, int preset, byte[] names, int[] len, int max_len); - int get_board_descr (int board_id, int preset, byte[] names, int[] len); + int get_board_descr (int board_id, int preset, byte[] names, int[] len, int max_len); - int get_device_name (int board_id, int preset, byte[] name, int[] len); + int get_device_name (int board_id, int preset, byte[] name, int[] len, int max_len); int get_board_presets (int board_id, int[] presets, int[] len); @@ -509,7 +511,7 @@ public static String[] get_eeg_names (int board_id, BrainFlowPresets preset) thr { int[] len = new int[1]; byte[] str = new byte[4096]; - int ec = instance.get_eeg_names (board_id, preset.get_code (), str, len); + int ec = instance.get_eeg_names (board_id, preset.get_code (), str, len, str.length); if (ec != BrainFlowExitCode.STATUS_OK.get_code ()) { throw new BrainFlowError ("Error in board info getter", ec); @@ -574,7 +576,7 @@ public static T get_board_descr (Class type, int board_id, BrainFlowPrese { int[] len = new int[1]; byte[] str = new byte[16000]; - int ec = instance.get_board_descr (board_id, preset.get_code (), str, len); + int ec = instance.get_board_descr (board_id, preset.get_code (), str, len, str.length); if (ec != BrainFlowExitCode.STATUS_OK.get_code ()) { throw new BrainFlowError ("Error in board info getter", ec); @@ -617,7 +619,7 @@ public static String get_device_name (int board_id, BrainFlowPresets preset) thr { int[] len = new int[1]; byte[] str = new byte[4096]; - int ec = instance.get_device_name (board_id, preset.get_code (), str, len); + int ec = instance.get_device_name (board_id, preset.get_code (), str, len, str.length); if (ec != BrainFlowExitCode.STATUS_OK.get_code ()) { throw new BrainFlowError ("Error in board info getter", ec); @@ -1217,7 +1219,7 @@ public static int[] get_gyro_channels (int board_id, BrainFlowPresets preset) th */ public static int[] get_gyro_channels (int board_id) throws BrainFlowError { - return get_gyro_channels (board_id); + return get_gyro_channels (board_id, BrainFlowPresets.DEFAULT_PRESET); } /** @@ -1358,6 +1360,28 @@ public int get_board_id () return master_board_id; } + /** + * get actual sampling rate for this prepared board session + */ + public int get_board_sampling_rate (BrainFlowPresets preset) throws BrainFlowError + { + int[] res = new int[1]; + int ec = instance.get_board_sampling_rate (preset.get_code (), res, board_id, input_json); + if (ec != BrainFlowExitCode.STATUS_OK.get_code ()) + { + throw new BrainFlowError ("Error in get_board_sampling_rate", ec); + } + return res[0]; + } + + /** + * get actual sampling rate for this prepared board session + */ + public int get_board_sampling_rate () throws BrainFlowError + { + return get_board_sampling_rate (BrainFlowPresets.DEFAULT_PRESET); + } + /** * add streamer */ @@ -1410,7 +1434,7 @@ public String config_board (String config) throws BrainFlowError { int[] len = new int[1]; byte[] str = new byte[4096]; - int ec = instance.config_board (config, str, len, board_id, input_json); + int ec = instance.config_board (config, str, len, str.length, board_id, input_json); if (ec != BrainFlowExitCode.STATUS_OK.get_code ()) { throw new BrainFlowError ("Error in config_board", ec); diff --git a/julia_package/brainflow/src/board_shim.jl b/julia_package/brainflow/src/board_shim.jl index cbc9c4081..d657c6d6d 100644 --- a/julia_package/brainflow/src/board_shim.jl +++ b/julia_package/brainflow/src/board_shim.jl @@ -136,7 +136,8 @@ end @brainflow_rethrow function get_eeg_names(board_id::BoardIdType, preset::PresetType=Integer(DEFAULT_PRESET)) names_string = Vector{Cuchar}(undef, 4096) len = Vector{Cint}(undef, 1) - ccall((:get_eeg_names, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Cint, Ptr{UInt8}, Ptr{Cint}), Int32(board_id), Int32(preset), names_string, len) + ccall((:get_eeg_names, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Cint, Ptr{UInt8}, Ptr{Cint}, Cint), + Int32(board_id), Int32(preset), names_string, len, length(names_string)) sub_string = String(names_string)[1:len[1]] value = split(sub_string, ',') return value @@ -145,7 +146,8 @@ end @brainflow_rethrow function get_board_descr(board_id::BoardIdType, preset::PresetType=Integer(DEFAULT_PRESET)) names_string = Vector{Cuchar}(undef, 16000) len = Vector{Cint}(undef, 1) - ccall((:get_board_descr, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Cint, Ptr{UInt8}, Ptr{Cint}), Int32(board_id), Int32(preset), names_string, len) + ccall((:get_board_descr, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Cint, Ptr{UInt8}, Ptr{Cint}, Cint), + Int32(board_id), Int32(preset), names_string, len, length(names_string)) sub_string = String(names_string)[1:len[1]] value = JSON.parse(sub_string) return value @@ -154,7 +156,8 @@ end @brainflow_rethrow function get_device_name(board_id::BoardIdType, preset::PresetType=Integer(DEFAULT_PRESET)) names_string = Vector{Cuchar}(undef, 4096) len = Vector{Cint}(undef, 1) - ccall((:get_device_name, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Cint, Ptr{UInt8}, Ptr{Cint}), Int32(board_id), Int32(preset), names_string, len) + ccall((:get_device_name, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Cint, Ptr{UInt8}, Ptr{Cint}, Cint), + Int32(board_id), Int32(preset), names_string, len, length(names_string)) sub_string = String(names_string)[1:len[1]] return sub_string end @@ -239,6 +242,15 @@ end BoardShim(id::BoardIds, params::BrainFlowInputParams) = BoardShim(Integer(id), params) BoardShim(id) = BoardShim(id, BrainFlowInputParams()) +@brainflow_rethrow function get_board_sampling_rate(board_shim::BoardShim, preset::PresetType=Integer(DEFAULT_PRESET)) + val = Vector{Cint}(undef, 1) + ccall((:get_board_sampling_rate, BOARD_CONTROLLER_INTERFACE), Cint, + (Cint, Ptr{Cint}, Cint, Ptr{UInt8}), Int32(preset), val, board_shim.board_id, + board_shim.input_json) + value = val[1] + return value +end + @brainflow_rethrow function prepare_session(board_shim::BoardShim) ccall((:prepare_session, BOARD_CONTROLLER_INTERFACE), Cint, (Cint, Ptr{UInt8}), board_shim.board_id, board_shim.input_json) end @@ -291,8 +303,8 @@ end @brainflow_rethrow function config_board(config::String, board_shim::BoardShim) resp_string = Vector{Cuchar}(undef, 4096) len = Vector{Cint}(undef, 1) - ccall((:config_board, BOARD_CONTROLLER_INTERFACE), Cint, (Ptr{UInt8}, Ptr{UInt8}, Ptr{Cint}, Cint, Ptr{UInt8}), - config, resp_string, len, board_shim.board_id, board_shim.input_json) + ccall((:config_board, BOARD_CONTROLLER_INTERFACE), Cint, (Ptr{UInt8}, Ptr{UInt8}, Ptr{Cint}, Cint, Cint, Ptr{UInt8}), + config, resp_string, len, length(resp_string), board_shim.board_id, board_shim.input_json) sub_string = String(resp_string)[1:len[1]] return sub_string end @@ -335,4 +347,4 @@ end num_samples, Int32(preset), val, data_size, board_shim.board_id, board_shim.input_json) value = transpose(reshape(val[1:data_size[1] * num_rows], (data_size[1], num_rows))) return value -end \ No newline at end of file +end diff --git a/matlab_package/brainflow/BoardShim.m b/matlab_package/brainflow/BoardShim.m index 248e2aba3..d245558a4 100644 --- a/matlab_package/brainflow/BoardShim.m +++ b/matlab_package/brainflow/BoardShim.m @@ -147,10 +147,12 @@ function log_message(log_level, message) % get board descr for provided board id task_name = 'get_board_descr'; lib_name = BoardShim.load_lib(); + str_len = libpointer('int32Ptr', 0); % no way to understand how it works in matlab, used this link % https://nl.mathworks.com/matlabcentral/answers/131446-what-data-type-do-i-need-to-calllib-with-pointer-argument-char% - [exit_code, board_descr] = calllib(lib_name, task_name, board_id, preset, blanks(16000), 16000); + [exit_code, board_descr] = calllib(lib_name, task_name, board_id, preset, blanks(16000), str_len, 16000); BoardShim.check_ec(exit_code, task_name); + board_descr = extractBefore(board_descr, str_len.Value + 1); board_descr = jsondecode(board_descr); end @@ -158,10 +160,12 @@ function log_message(log_level, message) % get eeg names for provided board id task_name = 'get_eeg_names'; lib_name = BoardShim.load_lib(); + str_len = libpointer('int32Ptr', 0); % no way to understand how it works in matlab, used this link % https://nl.mathworks.com/matlabcentral/answers/131446-what-data-type-do-i-need-to-calllib-with-pointer-argument-char% - [exit_code, eeg_names] = calllib(lib_name, task_name, board_id, preset, blanks(4096), 4096); + [exit_code, eeg_names] = calllib(lib_name, task_name, board_id, preset, blanks(4096), str_len, 4096); BoardShim.check_ec(exit_code, task_name); + eeg_names = extractBefore(eeg_names, str_len.Value + 1); eeg_names = split(eeg_names, ','); end @@ -191,10 +195,12 @@ function log_message(log_level, message) % get device name for provided board id task_name = 'get_device_name'; lib_name = BoardShim.load_lib(); + str_len = libpointer('int32Ptr', 0); % no way to understand how it works in matlab used this link % https://nl.mathworks.com/matlabcentral/answers/131446-what-data-type-do-i-need-to-calllib-with-pointer-argument-char% - [exit_code, device_name] = calllib(lib_name, task_name, board_id, preset, blanks(4096), 4096); + [exit_code, device_name] = calllib(lib_name, task_name, board_id, preset, blanks(4096), str_len, 4096); BoardShim.check_ec(exit_code, task_name); + device_name = extractBefore(device_name, str_len.Value + 1); end function eeg_channels = get_eeg_channels(board_id, preset) @@ -380,10 +386,12 @@ function prepare_session(obj) % send string to the board task_name = 'config_board'; lib_name = BoardShim.load_lib(); + str_len = libpointer('int32Ptr', 0); % no way to understand how it works in matlab used this link % https://nl.mathworks.com/matlabcentral/answers/131446-what-data-type-do-i-need-to-calllib-with-pointer-argument-char% - [exit_code, tmp, response] = calllib(lib_name, task_name, config, blanks(4096), 4096, obj.board_id, obj.input_params_json); + [exit_code, tmp, response] = calllib(lib_name, task_name, config, blanks(4096), str_len, 4096, obj.board_id, obj.input_params_json); BoardShim.check_ec(exit_code, task_name); + response = extractBefore(response, str_len.Value + 1); end function config_board_with_bytes(obj, bytes) @@ -497,6 +505,16 @@ function insert_marker(obj, value, preset) prepared = boolean(res.value); end + function sampling_rate = get_board_sampling_rate(obj, preset) + % get actual sampling rate for prepared board session + task_name = 'get_board_sampling_rate'; + lib_name = BoardShim.load_lib(); + res = libpointer('int32Ptr', 0); + exit_code = calllib(lib_name, task_name, preset, res, obj.board_id, obj.input_params_json); + BoardShim.check_ec(exit_code, task_name); + sampling_rate = res.value; + end + end end diff --git a/nodejs_package/brainflow/board_shim.ts b/nodejs_package/brainflow/board_shim.ts index 2a94e924e..bd5666e92 100644 --- a/nodejs_package/brainflow/board_shim.ts +++ b/nodejs_package/brainflow/board_shim.ts @@ -78,6 +78,7 @@ class BoardControllerDLL extends BoardControllerFunctions this.releaseSession = this.lib.func(CLike.release_session); this.stopStream = this.lib.func(CLike.stop_stream); this.getSamplingRate = this.lib.func(CLike.get_sampling_rate); + this.getBoardSamplingRate = this.lib.func(CLike.get_board_sampling_rate); this.getPackageNumChannel = this.lib.func(CLike.get_package_num_channel); this.getTimestampChannel = this.lib.func(CLike.get_timestamp_channel); this.getMarkerChannel = this.lib.func(CLike.get_marker_channel); @@ -279,7 +280,7 @@ export class BoardShim const len = [0]; let out = ['\0'.repeat(4096)]; const res = BoardControllerDLL.getInstance().configBoard( - config, out, len, this.boardId, this.inputJson); + config, out, len, out[0].length, this.boardId, this.inputJson); if (res !== BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res, 'Could not config board'); @@ -309,6 +310,18 @@ export class BoardShim return dataSize[0]; } + public getBoardSamplingRate(preset = BrainFlowPresets.DEFAULT_PRESET): number + { + const samplingRate = [0]; + const res = BoardControllerDLL.getInstance().getBoardSamplingRate( + preset, samplingRate, this.boardId, this.inputJson); + if (res !== BrainFlowExitCodes.STATUS_OK) + { + throw new BrainFlowError (res, 'Could not get board sampling rate'); + } + return samplingRate[0]; + } + public getBoardData(numSamples?: number, preset = BrainFlowPresets.DEFAULT_PRESET): number[][] { let dataSize = this.getBoardDataCount(preset); @@ -674,8 +687,9 @@ export class BoardShim public static getDeviceName(boardId: BoardIds, preset = BrainFlowPresets.DEFAULT_PRESET): string { const len = [0]; - let out = ['\0'.repeat(512)]; - const res = BoardControllerDLL.getInstance().getDeviceName(boardId, preset, out, len); + let out = ['\0'.repeat(4096)]; + const res = + BoardControllerDLL.getInstance().getDeviceName(boardId, preset, out, len, out[0].length); if (res !== BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res, 'Could not get device info'); @@ -687,7 +701,8 @@ export class BoardShim { const len = [0]; let out = ['\0'.repeat(4096)]; - const res = BoardControllerDLL.getInstance().getEegNames(boardId, preset, out, len); + const res = + BoardControllerDLL.getInstance().getEegNames(boardId, preset, out, len, out[0].length); if (res !== BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res, 'Could not get device info'); @@ -698,8 +713,9 @@ export class BoardShim public static getBoardDescr(boardId: BoardIds, preset = BrainFlowPresets.DEFAULT_PRESET): Object { const len = [0]; - let out = ['\0'.repeat(4096)]; - const res = BoardControllerDLL.getInstance().getBoardDescr(boardId, preset, out, len); + let out = ['\0'.repeat(16000)]; + const res = + BoardControllerDLL.getInstance().getBoardDescr(boardId, preset, out, len, out[0].length); if (res !== BrainFlowExitCodes.STATUS_OK) { throw new BrainFlowError (res, 'Could not get device info'); diff --git a/nodejs_package/brainflow/functions.types.ts b/nodejs_package/brainflow/functions.types.ts index 7d171cc1d..bb6a40203 100644 --- a/nodejs_package/brainflow/functions.types.ts +++ b/nodejs_package/brainflow/functions.types.ts @@ -32,7 +32,7 @@ export enum BoardControllerCLikeFunctions { add_streamer = 'int add_streamer (const char *streamer, int preset, int board_id, const char *json_brainflow_input_params)', config_board = - 'int config_board (const char *config, _Inout_ char *response, _Inout_ int *resp_len, int board_id, const char *json_brainflow_input_params)', + 'int config_board (const char *config, _Inout_ char *response, _Inout_ int *resp_len, int response_max_len, int board_id, const char *json_brainflow_input_params)', config_board_with_bytes = 'int config_board_with_bytes (const char *bytes, int len, int board_id, const char *json_brainflow_input_params)', delete_streamer = @@ -51,6 +51,8 @@ export enum BoardControllerCLikeFunctions { get_num_rows = 'int get_num_rows (int board_id, int preset, _Inout_ int *num_rows)', get_sampling_rate = 'int get_sampling_rate (int board_id, int preset, _Inout_ int *sampling_rate)', + get_board_sampling_rate = + 'int get_board_sampling_rate (int preset, _Inout_ int *sampling_rate, int board_id, const char *json_brainflow_input_params)', get_battery_channel = 'int get_battery_channel (int board_id, int preset, _Inout_ int *value)', get_package_num_channel = 'int get_package_num_channel (int board_id, int preset, _Inout_ int *value)', @@ -88,11 +90,11 @@ export enum BoardControllerCLikeFunctions { get_rotation_channels = 'int get_rotation_channels (int board_id, int preset, _Inout_ int *channels, _Inout_ int *len)', get_eeg_names = - 'int get_eeg_names (int board_id, int preset, _Inout_ char *eeg_names, _Inout_ int *len)', + 'int get_eeg_names (int board_id, int preset, _Inout_ char *eeg_names, _Inout_ int *len, int max_len)', get_device_name = - 'int get_device_name (int board_id, int preset, _Inout_ char *device_name, _Inout_ int *len)', + 'int get_device_name (int board_id, int preset, _Inout_ char *device_name, _Inout_ int *len, int max_len)', get_board_descr = - 'int get_board_descr (int board_id, int preset, _Inout_ char *descr, _Inout_ int *len)', + 'int get_board_descr (int board_id, int preset, _Inout_ char *descr, _Inout_ int *len, int max_len)', get_board_presets = 'int get_board_presets (int board_id, _Inout_ int *presets, _Inout_ int *len)', } @@ -138,6 +140,7 @@ export class BoardControllerFunctions config: string, response: string[], responseLen: number[], + responseMaxLen: number, boardId: BoardIds, inputJson: string, ) => BrainFlowExitCodes; @@ -181,6 +184,12 @@ export class BoardControllerFunctions boardId: BoardIds, preset: BrainFlowPresets, numRows: number[]) => BrainFlowExitCodes; getSamplingRate!: ( boardId: BoardIds, preset: BrainFlowPresets, samplingRate: number[]) => BrainFlowExitCodes; + getBoardSamplingRate!: ( + preset: BrainFlowPresets, + samplingRate: number[], + boardId: BoardIds, + inputJson: string, + ) => BrainFlowExitCodes; getEegChannels!: ( boardId: BoardIds, preset: BrainFlowPresets, @@ -276,12 +285,14 @@ export class BoardControllerFunctions preset: BrainFlowPresets, names: string[], len: number[], + maxLen: number, ) => BrainFlowExitCodes; getDeviceName!: ( boardId: BoardIds, preset: BrainFlowPresets, name: string[], len: number[], + maxLen: number, ) => BrainFlowExitCodes; getBoardPresets!: ( boardId: BoardIds, @@ -293,6 +304,7 @@ export class BoardControllerFunctions preset: BrainFlowPresets, descr: string[], len: number[], + maxLen: number, ) => BrainFlowExitCodes; } @@ -471,4 +483,4 @@ export class MLModuleFunctions inputJson: string) => BrainFlowExitCodes; releaseAll!: () => BrainFlowExitCodes; release!: (inputJson: string) => BrainFlowExitCodes; -} \ No newline at end of file +} diff --git a/python_package/brainflow/board_shim.py b/python_package/brainflow/board_shim.py index faf57da7e..56133cf07 100644 --- a/python_package/brainflow/board_shim.py +++ b/python_package/brainflow/board_shim.py @@ -327,6 +327,7 @@ def __init__(self): ndpointer(ctypes.c_ubyte), ndpointer(ctypes.c_int32), ctypes.c_int, + ctypes.c_int, ctypes.c_char_p ] @@ -347,6 +348,15 @@ def __init__(self): ndpointer(ctypes.c_int32) ] + self.get_board_sampling_rate = self.lib.get_board_sampling_rate + self.get_board_sampling_rate.restype = ctypes.c_int + self.get_board_sampling_rate.argtypes = [ + ctypes.c_int, + ndpointer(ctypes.c_int32), + ctypes.c_int, + ctypes.c_char_p + ] + self.get_battery_channel = self.lib.get_battery_channel self.get_battery_channel.restype = ctypes.c_int self.get_battery_channel.argtypes = [ @@ -393,7 +403,8 @@ def __init__(self): ctypes.c_int, ctypes.c_int, ndpointer(ctypes.c_ubyte), - ndpointer(ctypes.c_int32) + ndpointer(ctypes.c_int32), + ctypes.c_int ] self.get_board_presets = self.lib.get_board_presets @@ -418,7 +429,8 @@ def __init__(self): ctypes.c_int, ctypes.c_int, ndpointer(ctypes.c_ubyte), - ndpointer(ctypes.c_int32) + ndpointer(ctypes.c_int32), + ctypes.c_int ] self.get_device_name = self.lib.get_device_name @@ -427,7 +439,8 @@ def __init__(self): ctypes.c_int, ctypes.c_int, ndpointer(ctypes.c_ubyte), - ndpointer(ctypes.c_int32) + ndpointer(ctypes.c_int32), + ctypes.c_int ] self.get_eeg_channels = self.lib.get_eeg_channels @@ -783,7 +796,8 @@ def get_eeg_names(cls, board_id: int, preset: int = BrainFlowPresets.DEFAULT_PRE string = numpy.zeros(4096).astype(numpy.ubyte) string_len = numpy.zeros(1).astype(numpy.int32) - res = BoardControllerDLL.get_instance().get_eeg_names(board_id, preset, string, string_len) + res = BoardControllerDLL.get_instance().get_eeg_names( + board_id, preset, string, string_len, string.size) if res != BrainFlowExitCodes.STATUS_OK.value: raise BrainFlowError('unable to request info about this board', res) return string.tobytes().decode('utf-8')[0:string_len[0]].split(',') @@ -838,7 +852,8 @@ def get_board_descr(cls, board_id: int, preset: int = BrainFlowPresets.DEFAULT_P string = numpy.zeros(16000).astype(numpy.ubyte) string_len = numpy.zeros(1).astype(numpy.int32) - res = BoardControllerDLL.get_instance().get_board_descr(board_id, preset, string, string_len) + res = BoardControllerDLL.get_instance().get_board_descr( + board_id, preset, string, string_len, string.size) if res != BrainFlowExitCodes.STATUS_OK.value: raise BrainFlowError('unable to request info about this board', res) return json.loads(string.tobytes().decode('utf-8')[0:string_len[0]]) @@ -858,7 +873,8 @@ def get_device_name(cls, board_id: int, preset: int = BrainFlowPresets.DEFAULT_P string = numpy.zeros(4096).astype(numpy.ubyte) string_len = numpy.zeros(1).astype(numpy.int32) - res = BoardControllerDLL.get_instance().get_device_name(board_id, preset, string, string_len) + res = BoardControllerDLL.get_instance().get_device_name( + board_id, preset, string, string_len, string.size) if res != BrainFlowExitCodes.STATUS_OK.value: raise BrainFlowError('unable to request info about this board', res) return string.tobytes().decode('utf-8')[0:string_len[0]] @@ -1336,6 +1352,22 @@ def get_board_id(self) -> int: return self._master_board_id + def get_board_sampling_rate(self, preset: int = BrainFlowPresets.DEFAULT_PRESET) -> int: + """Get actual sampling rate for this prepared board session. + + :param preset: preset + :type preset: int + :return: sampling rate + :rtype: int + """ + + sampling_rate = numpy.zeros(1).astype(numpy.int32) + res = BoardControllerDLL.get_instance().get_board_sampling_rate( + preset, sampling_rate, self.board_id, self.input_json) + if res != BrainFlowExitCodes.STATUS_OK.value: + raise BrainFlowError('unable to get sampling rate for this board session', res) + return sampling_rate[0] + def insert_marker(self, value: float, preset: int = BrainFlowPresets.DEFAULT_PRESET) -> None: """Insert Marker to Data Stream @@ -1405,8 +1437,8 @@ def config_board(self, config) -> str: string = numpy.zeros(4096).astype(numpy.ubyte) string_len = numpy.zeros(1).astype(numpy.int32) - res = BoardControllerDLL.get_instance().config_board(config_string, string, string_len, self.board_id, - self.input_json) + res = BoardControllerDLL.get_instance().config_board( + config_string, string, string_len, string.size, self.board_id, self.input_json) if res != BrainFlowExitCodes.STATUS_OK.value: raise BrainFlowError('unable to config board', res) return string.tobytes().decode('utf-8')[0:string_len[0]] diff --git a/rust_package/brainflow/src/board_shim.rs b/rust_package/brainflow/src/board_shim.rs index 9abf1dec3..8e169c95c 100644 --- a/rust_package/brainflow/src/board_shim.rs +++ b/rust_package/brainflow/src/board_shim.rs @@ -226,6 +226,7 @@ impl BoardShim { config, result_char_buffer.as_mut_ptr(), &mut response_len, + result_char_buffer.len() as c_int, self.board_id as c_int, self.json_brainflow_input_params.as_ptr(), ); @@ -270,6 +271,21 @@ impl BoardShim { pub fn get_board_id(&self) -> BoardIds { return self.master_board_id; } + + /// Get actual sampling rate for this prepared board session. + pub fn get_board_sampling_rate(&self, preset: BrainFlowPresets) -> Result { + let mut sampling_rate = 0; + let res = unsafe { + board_controller::get_board_sampling_rate( + preset as c_int, + &mut sampling_rate, + self.board_id as c_int, + self.json_brainflow_input_params.as_ptr(), + ) + }; + check_brainflow_exit_code(res)?; + Ok(sampling_rate as usize) + } } /// Set BrainFlow log level, use it only if you want to write your own messages to BrainFlow logger, @@ -374,7 +390,13 @@ pub fn get_board_descr(board_id: BoardIds, preset: BrainFlowPresets) -> Result Result Result ::std::os::raw::c_int; } extern "C" { @@ -59,6 +60,7 @@ extern "C" { preset: ::std::os::raw::c_int, eeg_names: *mut ::std::os::raw::c_char, len: *mut ::std::os::raw::c_int, + max_len: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } extern "C" { @@ -187,6 +189,7 @@ extern "C" { preset: ::std::os::raw::c_int, name: *mut ::std::os::raw::c_char, len: *mut ::std::os::raw::c_int, + max_len: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } extern "C" { @@ -249,11 +252,20 @@ extern "C" { json_brainflow_input_params: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn get_board_sampling_rate( + preset: ::std::os::raw::c_int, + sampling_rate: *mut ::std::os::raw::c_int, + board_id: ::std::os::raw::c_int, + json_brainflow_input_params: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} extern "C" { pub fn config_board( config: *const ::std::os::raw::c_char, response: *mut ::std::os::raw::c_char, response_len: *mut ::std::os::raw::c_int, + response_max_len: ::std::os::raw::c_int, board_id: ::std::os::raw::c_int, json_brainflow_input_params: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; diff --git a/src/board_controller/aavaa/inc/aavaa_v3.h b/src/board_controller/aavaa/inc/aavaa_v3.h index 8fd3d2563..520e337ec 100644 --- a/src/board_controller/aavaa/inc/aavaa_v3.h +++ b/src/board_controller/aavaa/inc/aavaa_v3.h @@ -14,13 +14,13 @@ class AAVAAv3 : public BLELibBoard { public: AAVAAv3 (struct BrainFlowInputParams params); - ~AAVAAv3 (); + ~AAVAAv3 () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; int send_command (std::string config); void adapter_1_on_scan_start (simpleble_adapter_t adapter); diff --git a/src/board_controller/ant_neuro/ant_neuro.cpp b/src/board_controller/ant_neuro/ant_neuro.cpp index 11713a02d..a1801bebb 100644 --- a/src/board_controller/ant_neuro/ant_neuro.cpp +++ b/src/board_controller/ant_neuro/ant_neuro.cpp @@ -546,6 +546,15 @@ int AntNeuroBoard::config_board (std::string config, std::string &response) return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; } +int AntNeuroBoard::get_board_sampling_rate (int preset) +{ + if (preset != (int)BrainFlowPresets::DEFAULT_PRESET) + { + return Board::get_board_sampling_rate (preset); + } + return sampling_rate; +} + // stub for macos #else AntNeuroBoard::AntNeuroBoard (int board_id, struct BrainFlowInputParams params) @@ -586,4 +595,9 @@ int AntNeuroBoard::start_stream (int buffer_size, const char *streamer_params) safe_logger (spdlog::level::err, "AntNeuroBoard doesnt support MacOS."); return (int)BrainFlowExitCodes::UNSUPPORTED_BOARD_ERROR; } + +int AntNeuroBoard::get_board_sampling_rate (int preset) +{ + return Board::get_board_sampling_rate (preset); +} #endif diff --git a/src/board_controller/ant_neuro/inc/ant_neuro.h b/src/board_controller/ant_neuro/inc/ant_neuro.h index 2a0f85492..eec4fe4ef 100644 --- a/src/board_controller/ant_neuro/inc/ant_neuro.h +++ b/src/board_controller/ant_neuro/inc/ant_neuro.h @@ -37,11 +37,12 @@ class AntNeuroBoard : public Board public: AntNeuroBoard (int board_id, struct BrainFlowInputParams params); - ~AntNeuroBoard (); - - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + ~AntNeuroBoard () override; + + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; + int get_board_sampling_rate (int preset) override; }; diff --git a/src/board_controller/biolistener/inc/biolistener.h b/src/board_controller/biolistener/inc/biolistener.h index 704503fd8..480585304 100644 --- a/src/board_controller/biolistener/inc/biolistener.h +++ b/src/board_controller/biolistener/inc/biolistener.h @@ -65,11 +65,11 @@ class BioListener : public Board public: BioListener (int board_id, struct BrainFlowInputParams params); - ~BioListener (); + ~BioListener () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/board_controller.cpp b/src/board_controller/board_controller.cpp index 3e52792af..045edeab4 100644 --- a/src/board_controller/board_controller.cpp +++ b/src/board_controller/board_controller.cpp @@ -69,6 +69,8 @@ static int check_board_session (int board_id, const char *json_brainflow_input_p std::pair &key, bool log_error = true); static int string_to_brainflow_input_params ( const char *json_brainflow_input_params, struct BrainFlowInputParams *params); +static int copy_string_to_buffer ( + const std::string &source, char *destination, int *destination_len, int max_len); int prepare_session (int board_id, const char *json_brainflow_input_params) @@ -443,6 +445,31 @@ int get_board_data (int data_count, int preset, double *data_buf, int board_id, return board_it->second->get_board_data (data_count, preset, data_buf); } +int get_board_sampling_rate ( + int preset, int *sampling_rate, int board_id, const char *json_brainflow_input_params) +{ + std::lock_guard lock (mutex); + if (sampling_rate == NULL) + { + return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; + } + + std::pair key; + int res = check_board_session (board_id, json_brainflow_input_params, key, false); + if (res != (int)BrainFlowExitCodes::STATUS_OK) + { + return res; + } + auto board_it = boards.find (key); + int value = board_it->second->get_board_sampling_rate (preset); + if (value <= 0) + { + return (int)BrainFlowExitCodes::UNSUPPORTED_BOARD_ERROR; + } + *sampling_rate = value; + return (int)BrainFlowExitCodes::STATUS_OK; +} + int set_log_level_board_controller (int log_level) { std::lock_guard lock (mutex); @@ -482,11 +509,11 @@ int java_set_jnienv (JNIEnv *java_jnienv) return (int)BrainFlowExitCodes::STATUS_OK; } -int config_board (const char *config, char *response, int *response_len, int board_id, - const char *json_brainflow_input_params) +int config_board (const char *config, char *response, int *response_len, int response_max_len, + int board_id, const char *json_brainflow_input_params) { std::lock_guard lock (mutex); - if ((config == NULL) || (response == NULL) || (response_len == NULL)) + if ((config == NULL) || (response == NULL) || (response_len == NULL) || (response_max_len < 1)) { return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; } @@ -503,8 +530,7 @@ int config_board (const char *config, char *response, int *response_len, int boa res = board_it->second->config_board (conf, resp); if (res == (int)BrainFlowExitCodes::STATUS_OK) { - *response_len = (int)resp.length (); - strcpy (response, resp.c_str ()); + res = copy_string_to_buffer (resp, response, response_len, response_max_len); } return res; } @@ -547,6 +573,27 @@ int add_streamer ( return board_it->second->add_streamer (streamer, preset); } +static int copy_string_to_buffer ( + const std::string &source, char *destination, int *destination_len, int max_len) +{ + if ((destination == NULL) || (destination_len == NULL) || (max_len < 1)) + { + return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; + } + + *destination_len = (int)source.size (); + if (((int)source.size () + 1) > max_len) + { + destination[0] = '\0'; + Board::board_logger->error ("provided output buffer is too small, required {}, got {}", + source.size () + 1, max_len); + return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; + } + + memcpy (destination, source.c_str (), source.size () + 1); + return (int)BrainFlowExitCodes::STATUS_OK; +} + int delete_streamer ( const char *streamer, int preset, int board_id, const char *json_brainflow_input_params) { diff --git a/src/board_controller/board_info_getter.cpp b/src/board_controller/board_info_getter.cpp index 4ddd5a1e9..4815a8ce0 100644 --- a/src/board_controller/board_info_getter.cpp +++ b/src/board_controller/board_info_getter.cpp @@ -13,10 +13,12 @@ static int get_single_value ( int board_id, int preset, const char *param_name, int *value, bool use_logger = true); static int get_string_value (int board_id, int preset, const char *param_name, char *string, - int *len, bool use_logger = true); + int *len, int max_len, bool use_logger = true); static int get_array_value (int board_id, int preset, const char *param_name, int *output_array, int *len, bool use_logger = true); static std::string get_preset_str (int preset); +static int copy_string_value ( + const std::string &value, char *destination, int *len, int max_len, bool use_logger); int get_board_presets (int board_id, int *presets, int *len) { @@ -63,7 +65,7 @@ int get_board_presets (int board_id, int *presets, int *len) } } -int get_board_descr (int board_id, int preset, char *board_descr, int *len) +int get_board_descr (int board_id, int preset, char *board_descr, int *len, int max_len) { std::string preset_str = get_preset_str (preset); try @@ -77,9 +79,7 @@ int get_board_descr (int board_id, int preset, char *board_descr, int *len) } else { - strcpy (board_descr, res.c_str ()); - *len = (int)strlen (res.c_str ()); - return (int)BrainFlowExitCodes::STATUS_OK; + return copy_string_value (res, board_descr, len, max_len, true); } } catch (json::exception &e) @@ -121,14 +121,14 @@ int get_timestamp_channel (int board_id, int preset, int *timestamp_channel) return get_single_value (board_id, preset, "timestamp_channel", timestamp_channel); } -int get_eeg_names (int board_id, int preset, char *eeg_names, int *len) +int get_eeg_names (int board_id, int preset, char *eeg_names, int *len, int max_len) { - return get_string_value (board_id, preset, "eeg_names", eeg_names, len); + return get_string_value (board_id, preset, "eeg_names", eeg_names, len, max_len); } -int get_device_name (int board_id, int preset, char *name, int *len) +int get_device_name (int board_id, int preset, char *name, int *len, int max_len) { - return get_string_value (board_id, preset, "name", name, len); + return get_string_value (board_id, preset, "name", name, len, max_len); } int get_eeg_channels (int board_id, int preset, int *eeg_channels, int *len) @@ -294,8 +294,8 @@ static int get_array_value ( } } -static int get_string_value ( - int board_id, int preset, const char *param_name, char *string, int *len, bool use_logger) +static int get_string_value (int board_id, int preset, const char *param_name, char *string, + int *len, int max_len, bool use_logger) { std::string preset_str = get_preset_str (preset); if (preset_str.empty ()) @@ -307,9 +307,7 @@ static int get_string_value ( std::string val = boards_struct .brainflow_boards_json["boards"][std::to_string (board_id)][preset_str][param_name]; - strcpy (string, val.c_str ()); - *len = (int)strlen (val.c_str ()); - return (int)BrainFlowExitCodes::STATUS_OK; + return copy_string_value (val, string, len, max_len, use_logger); } catch (json::exception &e) { @@ -344,4 +342,28 @@ static std::string get_preset_str (int preset) Board::board_logger->error ("unknown preset"); } return preset_str; -} \ No newline at end of file +} + +static int copy_string_value ( + const std::string &value, char *destination, int *len, int max_len, bool use_logger) +{ + if ((destination == NULL) || (len == NULL) || (max_len < 1)) + { + return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; + } + + *len = (int)value.size (); + if (((int)value.size () + 1) > max_len) + { + destination[0] = '\0'; + if (use_logger) + { + Board::board_logger->error ("provided output buffer is too small, required {}, got {}", + value.size () + 1, max_len); + } + return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; + } + + memcpy (destination, value.c_str (), value.size () + 1); + return (int)BrainFlowExitCodes::STATUS_OK; +} diff --git a/src/board_controller/brainalive/inc/brainalive.h b/src/board_controller/brainalive/inc/brainalive.h index 46046c9b7..e7f59a4d5 100644 --- a/src/board_controller/brainalive/inc/brainalive.h +++ b/src/board_controller/brainalive/inc/brainalive.h @@ -16,13 +16,13 @@ class BrainAlive : public BLELibBoard public: BrainAlive (struct BrainFlowInputParams params); - ~BrainAlive (); + ~BrainAlive () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; int config_board (std::string config); void adapter_1_on_scan_found (simpleble_adapter_t adapter, simpleble_peripheral_t peripheral); diff --git a/src/board_controller/emotibit/inc/emotibit.h b/src/board_controller/emotibit/inc/emotibit.h index c32c4163b..de175972d 100644 --- a/src/board_controller/emotibit/inc/emotibit.h +++ b/src/board_controller/emotibit/inc/emotibit.h @@ -59,11 +59,11 @@ class Emotibit : public Board public: Emotibit (struct BrainFlowInputParams params); - ~Emotibit (); + ~Emotibit () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); -}; \ No newline at end of file + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; +}; diff --git a/src/board_controller/enophone/inc/enophone.h b/src/board_controller/enophone/inc/enophone.h index c9eb3fca7..94377d5c4 100644 --- a/src/board_controller/enophone/inc/enophone.h +++ b/src/board_controller/enophone/inc/enophone.h @@ -19,15 +19,15 @@ class Enophone : public BTLibBoard volatile int state; void read_thread (); - std::string get_name_selector (); + std::string get_name_selector () override; public: Enophone (struct BrainFlowInputParams params); - ~Enophone (); + ~Enophone () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/freeeeg/inc/freeeeg.h b/src/board_controller/freeeeg/inc/freeeeg.h index 64d6431a2..0518c4a0e 100644 --- a/src/board_controller/freeeeg/inc/freeeeg.h +++ b/src/board_controller/freeeeg/inc/freeeeg.h @@ -26,13 +26,13 @@ class FreeEEG : public Board public: FreeEEG (int board_id, struct BrainFlowInputParams params); - ~FreeEEG (); + ~FreeEEG () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; static constexpr int start_byte = 0xA0; static constexpr int end_byte = 0xC0; diff --git a/src/board_controller/gtec/inc/unicorn_board.h b/src/board_controller/gtec/inc/unicorn_board.h index 6c293e990..056e19305 100644 --- a/src/board_controller/gtec/inc/unicorn_board.h +++ b/src/board_controller/gtec/inc/unicorn_board.h @@ -36,13 +36,13 @@ class UnicornBoard : public Board public: UnicornBoard (struct BrainFlowInputParams params); - ~UnicornBoard (); + ~UnicornBoard () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; static constexpr int package_size = 17; // from unicorn.h }; diff --git a/src/board_controller/inc/ble_lib_board.h b/src/board_controller/inc/ble_lib_board.h index 50d0c580d..6bdeadc31 100644 --- a/src/board_controller/inc/ble_lib_board.h +++ b/src/board_controller/inc/ble_lib_board.h @@ -71,5 +71,5 @@ class BLELibBoard : public Board public: BLELibBoard (int board_id, struct BrainFlowInputParams params); - virtual ~BLELibBoard (); + ~BLELibBoard () override; }; diff --git a/src/board_controller/inc/board.h b/src/board_controller/inc/board.h index 29e66c21b..5e09f5a68 100644 --- a/src/board_controller/inc/board.h +++ b/src/board_controller/inc/board.h @@ -53,6 +53,18 @@ class Board virtual int stop_stream () = 0; virtual int release_session () = 0; virtual int config_board (std::string config, std::string &response) = 0; + virtual int get_board_sampling_rate (int preset) + { + try + { + return board_descr.at (preset_to_string (preset)).at ("sampling_rate").get (); + } + catch (json::exception &e) + { + safe_logger (spdlog::level::err, e.what ()); + } + return -1; + } // some devices may implement it but there is no requirement to have this method and we do not // recommend anybody to use it diff --git a/src/board_controller/inc/board_controller.h b/src/board_controller/inc/board_controller.h index d909a9df8..f50f8f147 100644 --- a/src/board_controller/inc/board_controller.h +++ b/src/board_controller/inc/board_controller.h @@ -22,8 +22,11 @@ extern "C" int preset, int *result, int board_id, const char *json_brainflow_input_params); SHARED_EXPORT int CALLING_CONVENTION get_board_data (int data_count, int preset, double *data_buf, int board_id, const char *json_brainflow_input_params); + SHARED_EXPORT int CALLING_CONVENTION get_board_sampling_rate ( + int preset, int *sampling_rate, int board_id, const char *json_brainflow_input_params); SHARED_EXPORT int CALLING_CONVENTION config_board (const char *config, char *response, - int *response_len, int board_id, const char *json_brainflow_input_params); + int *response_len, int response_max_len, int board_id, + const char *json_brainflow_input_params); SHARED_EXPORT int CALLING_CONVENTION config_board_with_bytes ( const char *bytes, int len, int board_id, const char *json_brainflow_input_params); SHARED_EXPORT int CALLING_CONVENTION is_prepared ( diff --git a/src/board_controller/inc/board_info_getter.h b/src/board_controller/inc/board_info_getter.h index 727040d3f..34ed7854a 100644 --- a/src/board_controller/inc/board_info_getter.h +++ b/src/board_controller/inc/board_info_getter.h @@ -8,7 +8,7 @@ extern "C" #endif // data and board desc methods SHARED_EXPORT int CALLING_CONVENTION get_board_descr ( - int board_id, int preset, char *board_descr, int *len); + int board_id, int preset, char *board_descr, int *len, int max_len); SHARED_EXPORT int CALLING_CONVENTION get_sampling_rate ( int board_id, int preset, int *sampling_rate); SHARED_EXPORT int CALLING_CONVENTION get_package_num_channel ( @@ -21,7 +21,7 @@ extern "C" int board_id, int preset, int *battery_channel); SHARED_EXPORT int CALLING_CONVENTION get_num_rows (int board_id, int preset, int *num_rows); SHARED_EXPORT int CALLING_CONVENTION get_eeg_names ( - int board_id, int preset, char *eeg_names, int *len); + int board_id, int preset, char *eeg_names, int *len, int max_len); SHARED_EXPORT int CALLING_CONVENTION get_exg_channels ( int board_id, int preset, int *exg_channels, int *len); SHARED_EXPORT int CALLING_CONVENTION get_eeg_channels ( @@ -53,7 +53,7 @@ extern "C" SHARED_EXPORT int CALLING_CONVENTION get_magnetometer_channels ( int board_id, int preset, int *magnetometer_channels, int *len); SHARED_EXPORT int CALLING_CONVENTION get_device_name ( - int board_id, int preset, char *name, int *len); + int board_id, int preset, char *name, int *len, int max_len); SHARED_EXPORT int CALLING_CONVENTION get_board_presets (int board_id, int *presets, int *len); #ifdef __cplusplus diff --git a/src/board_controller/inc/bt_lib_board.h b/src/board_controller/inc/bt_lib_board.h index b992555f1..c3e41d728 100644 --- a/src/board_controller/inc/bt_lib_board.h +++ b/src/board_controller/inc/bt_lib_board.h @@ -24,9 +24,9 @@ class BTLibBoard : public Board public: BTLibBoard (int board_id, struct BrainFlowInputParams params); - virtual ~BTLibBoard (); + ~BTLibBoard () override; - virtual int prepare_session (); - virtual int release_session (); - virtual int config_board (std::string config, std::string &response); + int prepare_session () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/inc/dyn_lib_board.h b/src/board_controller/inc/dyn_lib_board.h index cf35354e0..a08158058 100644 --- a/src/board_controller/inc/dyn_lib_board.h +++ b/src/board_controller/inc/dyn_lib_board.h @@ -45,7 +45,7 @@ class DynLibBoard : public Board public: DynLibBoard (int board_id, struct BrainFlowInputParams params); - virtual ~DynLibBoard (); + ~DynLibBoard () override; int prepare_session () override; int start_stream (int buffer_size, const char *streamer_params) override; diff --git a/src/board_controller/inc/playback_file_board.h b/src/board_controller/inc/playback_file_board.h index cb59ba2d6..0eb93e65c 100644 --- a/src/board_controller/inc/playback_file_board.h +++ b/src/board_controller/inc/playback_file_board.h @@ -21,16 +21,17 @@ class PlaybackFileBoard : public Board bool initialized; std::vector> file_offsets; + int validate_file_access (const std::string &filename); void read_thread (int preset, std::string filename); int get_file_offsets (std::string filename, std::vector &offsets); public: PlaybackFileBoard (struct BrainFlowInputParams params); - ~PlaybackFileBoard (); + ~PlaybackFileBoard () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/inc/streaming_board.h b/src/board_controller/inc/streaming_board.h index 7c0696cb5..acf203595 100644 --- a/src/board_controller/inc/streaming_board.h +++ b/src/board_controller/inc/streaming_board.h @@ -24,11 +24,11 @@ class StreamingBoard : public Board public: StreamingBoard (struct BrainFlowInputParams params); - ~StreamingBoard (); + ~StreamingBoard () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/inc/synthetic_board.h b/src/board_controller/inc/synthetic_board.h index 3af3d30e4..34260c00c 100644 --- a/src/board_controller/inc/synthetic_board.h +++ b/src/board_controller/inc/synthetic_board.h @@ -19,12 +19,12 @@ class SyntheticBoard : public Board public: SyntheticBoard (struct BrainFlowInputParams params); - ~SyntheticBoard (); - - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); - int config_board_with_bytes (const char *bytes, int len); + ~SyntheticBoard () override; + + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; + int config_board_with_bytes (const char *bytes, int len) override; }; diff --git a/src/board_controller/mentalab/explore.cpp b/src/board_controller/mentalab/explore.cpp index aa483a541..b5ea53d52 100644 --- a/src/board_controller/mentalab/explore.cpp +++ b/src/board_controller/mentalab/explore.cpp @@ -12,6 +12,7 @@ Explore::Explore (int board_id, struct BrainFlowInputParams params) : BTLibBoard keep_alive = false; last_eeg_timestamp = -1; state = (int)BrainFlowExitCodes::SYNC_TIMEOUT_ERROR; + eeg_sampling_rate = Board::get_board_sampling_rate ((int)BrainFlowPresets::DEFAULT_PRESET); } Explore::~Explore () @@ -32,6 +33,8 @@ int Explore::prepare_session () int Explore::config_board (std::string config, std::string &response) { bool prefix_found = false; + bool sampling_rate_updated = false; + int new_sampling_rate = 0; constexpr int command_len = 14; unsigned char command[command_len]; memset (command, 0, command_len); @@ -56,7 +59,6 @@ int Explore::config_board (std::string config, std::string &response) if (config.find (sps_prefix) != std::string::npos) { prefix_found = true; - int new_sampling_rate = 0; std::string value = config.substr (sps_prefix.size ()); try { @@ -80,6 +82,7 @@ int Explore::config_board (std::string config, std::string &response) command[9] = 0x02; if (new_sampling_rate == 1000) command[9] = 0x03; + sampling_rate_updated = true; } std::string test_sig_prefix = "test_signal:"; if (config.find (test_sig_prefix) != std::string::npos) @@ -151,9 +154,22 @@ int Explore::config_board (std::string config, std::string &response) safe_logger (spdlog::level::err, "failed to config device, res: {}", res); return (int)BrainFlowExitCodes::BOARD_WRITE_ERROR; } + if (sampling_rate_updated) + { + eeg_sampling_rate = new_sampling_rate; + } return (int)BrainFlowExitCodes::STATUS_OK; } +int Explore::get_board_sampling_rate (int preset) +{ + if (preset == (int)BrainFlowPresets::DEFAULT_PRESET) + { + return eeg_sampling_rate; + } + return Board::get_board_sampling_rate (preset); +} + int Explore::start_stream (int buffer_size, const char *streamer_params) { if (!initialized) @@ -498,4 +514,4 @@ double Explore::get_battery_percentage (double battery) percentage = 100; return percentage; -} \ No newline at end of file +} diff --git a/src/board_controller/mentalab/inc/explore.h b/src/board_controller/mentalab/inc/explore.h index f12cb44bf..4c47f7ea8 100644 --- a/src/board_controller/mentalab/inc/explore.h +++ b/src/board_controller/mentalab/inc/explore.h @@ -36,9 +36,10 @@ class Explore : public BTLibBoard std::mutex m; std::condition_variable cv; double last_eeg_timestamp; + int eeg_sampling_rate; void read_thread (); - std::string get_name_selector (); + std::string get_name_selector () override; void parse_eeg_data (const ExploreHeader *header, double *package, unsigned char *payload, double vref, int n_packages); void parse_orientation_data ( @@ -48,11 +49,12 @@ class Explore : public BTLibBoard public: Explore (int board_id, struct BrainFlowInputParams params); - ~Explore (); - - int prepare_session (); - int config_board (std::string config, std::string &response); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); + ~Explore () override; + + int prepare_session () override; + int config_board (std::string config, std::string &response) override; + int get_board_sampling_rate (int preset) override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; }; diff --git a/src/board_controller/muse/inc/muse.h b/src/board_controller/muse/inc/muse.h index 188826b9b..31a281715 100644 --- a/src/board_controller/muse/inc/muse.h +++ b/src/board_controller/muse/inc/muse.h @@ -32,13 +32,13 @@ class Muse : public BLELibBoard public: Muse (int board_id, struct BrainFlowInputParams params); - ~Muse (); + ~Muse () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; int config_board (std::string config); void adapter_on_scan_found (simpleble_adapter_t adapter, simpleble_peripheral_t peripheral); diff --git a/src/board_controller/muse/inc/muse_bled.h b/src/board_controller/muse/inc/muse_bled.h index 4540e4694..e308d88f1 100644 --- a/src/board_controller/muse/inc/muse_bled.h +++ b/src/board_controller/muse/inc/muse_bled.h @@ -12,11 +12,11 @@ class MuseBLED : public DynLibBoard public: MuseBLED (int board_id, struct BrainFlowInputParams params); - ~MuseBLED (); + ~MuseBLED () override; - int prepare_session (); + int prepare_session () override; protected: - std::string get_lib_name (); - void read_thread (); + std::string get_lib_name () override; + void read_thread () override; }; diff --git a/src/board_controller/neuromd/inc/brainbit.h b/src/board_controller/neuromd/inc/brainbit.h index c83ec837a..75671f9dc 100644 --- a/src/board_controller/neuromd/inc/brainbit.h +++ b/src/board_controller/neuromd/inc/brainbit.h @@ -42,13 +42,13 @@ class BrainBit : public NeuromdBoard public: BrainBit (struct BrainFlowInputParams params); - ~BrainBit (); + ~BrainBit () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; #if defined _WIN32 || defined __APPLE__ // callbacks must be public since they are called from plain C callbacks diff --git a/src/board_controller/neuromd/inc/brainbit_bled.h b/src/board_controller/neuromd/inc/brainbit_bled.h index cdc643e52..580c7aa88 100644 --- a/src/board_controller/neuromd/inc/brainbit_bled.h +++ b/src/board_controller/neuromd/inc/brainbit_bled.h @@ -13,11 +13,11 @@ class BrainBitBLED : public DynLibBoard public: BrainBitBLED (struct BrainFlowInputParams params); - ~BrainBitBLED (); + ~BrainBitBLED () override; - int prepare_session (); + int prepare_session () override; protected: - std::string get_lib_name (); - virtual int call_open (); + std::string get_lib_name () override; + int call_open () override; }; diff --git a/src/board_controller/neuromd/inc/callibri.h b/src/board_controller/neuromd/inc/callibri.h index 876804d5d..aa537ed35 100644 --- a/src/board_controller/neuromd/inc/callibri.h +++ b/src/board_controller/neuromd/inc/callibri.h @@ -30,11 +30,11 @@ class Callibri : public NeuromdBoard public: Callibri (int board_id, struct BrainFlowInputParams params); - ~Callibri (); + ~Callibri () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/neuromd/inc/callibri_ecg.h b/src/board_controller/neuromd/inc/callibri_ecg.h index d8a9da2d1..568b48c97 100644 --- a/src/board_controller/neuromd/inc/callibri_ecg.h +++ b/src/board_controller/neuromd/inc/callibri_ecg.h @@ -8,7 +8,7 @@ class CallibriECG : public Callibri #if defined _WIN32 || defined __APPLE__ protected: - int apply_initial_settings (); + int apply_initial_settings () override; #endif public: @@ -16,7 +16,7 @@ class CallibriECG : public Callibri : Callibri ((int)BoardIds::CALLIBRI_ECG_BOARD, params) { } - ~CallibriECG () + ~CallibriECG () override { } }; diff --git a/src/board_controller/neuromd/inc/callibri_eeg.h b/src/board_controller/neuromd/inc/callibri_eeg.h index 4205ae034..ff38350b4 100644 --- a/src/board_controller/neuromd/inc/callibri_eeg.h +++ b/src/board_controller/neuromd/inc/callibri_eeg.h @@ -8,7 +8,7 @@ class CallibriEEG : public Callibri #if defined _WIN32 || defined __APPLE__ protected: - int apply_initial_settings (); + int apply_initial_settings () override; #endif public: @@ -16,7 +16,7 @@ class CallibriEEG : public Callibri : Callibri ((int)BoardIds::CALLIBRI_EEG_BOARD, params) { } - ~CallibriEEG () + ~CallibriEEG () override { } }; diff --git a/src/board_controller/neuromd/inc/callibri_emg.h b/src/board_controller/neuromd/inc/callibri_emg.h index 8411bdae7..4439d5fa8 100644 --- a/src/board_controller/neuromd/inc/callibri_emg.h +++ b/src/board_controller/neuromd/inc/callibri_emg.h @@ -8,7 +8,7 @@ class CallibriEMG : public Callibri #if defined _WIN32 || defined __APPLE__ protected: - int apply_initial_settings (); + int apply_initial_settings () override; #endif public: @@ -16,7 +16,7 @@ class CallibriEMG : public Callibri : Callibri ((int)BoardIds::CALLIBRI_EMG_BOARD, params) { } - ~CallibriEMG () + ~CallibriEMG () override { } }; diff --git a/src/board_controller/neuromd/inc/neuromd_board.h b/src/board_controller/neuromd/inc/neuromd_board.h index c6506cade..9a523723e 100644 --- a/src/board_controller/neuromd/inc/neuromd_board.h +++ b/src/board_controller/neuromd/inc/neuromd_board.h @@ -76,9 +76,9 @@ class NeuromdBoard : public Board #endif public: - virtual int prepare_session (); - virtual int release_session (); + int prepare_session () override; + int release_session () override; NeuromdBoard (int board_id, struct BrainFlowInputParams params); - virtual ~NeuromdBoard (); + ~NeuromdBoard () override; }; diff --git a/src/board_controller/neuropawn/inc/knight.h b/src/board_controller/neuropawn/inc/knight.h index 93d948f9b..2ccd58233 100644 --- a/src/board_controller/neuropawn/inc/knight.h +++ b/src/board_controller/neuropawn/inc/knight.h @@ -6,8 +6,8 @@ class Knight : public KnightBase { protected: - void read_thread (); + void read_thread () override; public: Knight (int board_id, struct BrainFlowInputParams params); -}; \ No newline at end of file +}; diff --git a/src/board_controller/neuropawn/inc/knight_base.h b/src/board_controller/neuropawn/inc/knight_base.h index 2381a00aa..68d79355c 100644 --- a/src/board_controller/neuropawn/inc/knight_base.h +++ b/src/board_controller/neuropawn/inc/knight_base.h @@ -29,13 +29,13 @@ class KnightBase : public Board private: public: KnightBase (int board_id, struct BrainFlowInputParams params); - virtual ~KnightBase (); + ~KnightBase () override; - virtual int prepare_session (); - virtual int start_stream (int buffer_size, const char *streamer_params); - virtual int stop_stream (); - virtual int release_session (); - virtual int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; static constexpr int start_byte = 0xA0; static constexpr int end_byte = 0xC0; diff --git a/src/board_controller/neuropawn/inc/knight_imu.h b/src/board_controller/neuropawn/inc/knight_imu.h index 70b0c2c39..54309b588 100644 --- a/src/board_controller/neuropawn/inc/knight_imu.h +++ b/src/board_controller/neuropawn/inc/knight_imu.h @@ -6,8 +6,8 @@ class KnightIMU : public KnightBase { protected: - void read_thread (); + void read_thread () override; public: KnightIMU (int board_id, struct BrainFlowInputParams params); -}; \ No newline at end of file +}; diff --git a/src/board_controller/neurosity/inc/notion_osc.h b/src/board_controller/neurosity/inc/notion_osc.h index 81a356481..dfac7ce9f 100644 --- a/src/board_controller/neurosity/inc/notion_osc.h +++ b/src/board_controller/neurosity/inc/notion_osc.h @@ -31,11 +31,11 @@ class NotionOSC : public Board public: NotionOSC (int board_id, struct BrainFlowInputParams params); - ~NotionOSC (); + ~NotionOSC () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/ntl/inc/ntl_wifi.h b/src/board_controller/ntl/inc/ntl_wifi.h index 3d880c9b6..d5298a0a1 100644 --- a/src/board_controller/ntl/inc/ntl_wifi.h +++ b/src/board_controller/ntl/inc/ntl_wifi.h @@ -13,7 +13,7 @@ class NtlWifi : public OpenBCIWifiShieldBoard double accel_scale = (double)(0.002 / (pow (2, 4))); protected: - void read_thread (); + void read_thread () override; public: // package num, 8 eeg channels, 3 accel channels @@ -22,5 +22,5 @@ class NtlWifi : public OpenBCIWifiShieldBoard { } - int prepare_session (); + int prepare_session () override; }; diff --git a/src/board_controller/openbci/galea.cpp b/src/board_controller/openbci/galea.cpp index 2473a7eac..8ef0f3365 100644 --- a/src/board_controller/openbci/galea.cpp +++ b/src/board_controller/openbci/galea.cpp @@ -31,6 +31,7 @@ Galea::Galea (struct BrainFlowInputParams params) : Board ((int)BoardIds::GALEA_ initialized = false; state = (int)BrainFlowExitCodes::SYNC_TIMEOUT_ERROR; half_rtt = 0.0; + current_sampling_rate = Board::get_board_sampling_rate ((int)BrainFlowPresets::DEFAULT_PRESET); } Galea::~Galea () @@ -182,6 +183,7 @@ int Galea::config_board (std::string conf, std::string &response) switch (b[0]) { case 'A': + track_openbci_sampling_rate (board_id, conf, current_sampling_rate); return (int)BrainFlowExitCodes::STATUS_OK; case 'I': safe_logger (spdlog::level::err, "invalid command"); @@ -193,6 +195,7 @@ int Galea::config_board (std::string conf, std::string &response) } else { + track_openbci_sampling_rate (board_id, conf, current_sampling_rate); safe_logger (spdlog::level::warn, "reconfiguring device during the streaming may lead to inconsistent data, it's " "recommended to call stop_stream before config_board"); @@ -201,6 +204,15 @@ int Galea::config_board (std::string conf, std::string &response) return (int)BrainFlowExitCodes::STATUS_OK; } +int Galea::get_board_sampling_rate (int preset) +{ + if (preset != (int)BrainFlowPresets::DEFAULT_PRESET) + { + return Board::get_board_sampling_rate (preset); + } + return current_sampling_rate; +} + int Galea::start_stream (int buffer_size, const char *streamer_params) { if (!initialized) @@ -653,4 +665,4 @@ std::string Galea::find_device () udp_client.close (); return ip_address; -} \ No newline at end of file +} diff --git a/src/board_controller/openbci/ganglion.cpp b/src/board_controller/openbci/ganglion.cpp index 872789eba..2cb71b058 100644 --- a/src/board_controller/openbci/ganglion.cpp +++ b/src/board_controller/openbci/ganglion.cpp @@ -37,6 +37,7 @@ Ganglion::Ganglion (struct BrainFlowInputParams params) state = (int)BrainFlowExitCodes::SYNC_TIMEOUT_ERROR; start_command = "b"; stop_command = "s"; + current_sampling_rate = Board::get_board_sampling_rate ((int)BrainFlowPresets::DEFAULT_PRESET); std::string ganglionlib_path = ""; std::string ganglionlib_name = ""; @@ -642,13 +643,27 @@ int Ganglion::config_board (std::string config, std::string &response) } else { - return call_config (const_cast (conf)); + int res = call_config (const_cast (conf)); + if (res == (int)BrainFlowExitCodes::STATUS_OK) + { + track_openbci_sampling_rate (board_id, config, current_sampling_rate); + } + return res; } } } return (int)BrainFlowExitCodes::STATUS_OK; } +int Ganglion::get_board_sampling_rate (int preset) +{ + if (preset != (int)BrainFlowPresets::DEFAULT_PRESET) + { + return Board::get_board_sampling_rate (preset); + } + return current_sampling_rate; +} + int Ganglion::call_init () { if (dll_loader == NULL) diff --git a/src/board_controller/openbci/ganglion_native.cpp b/src/board_controller/openbci/ganglion_native.cpp index 636aa99de..25b995b3b 100644 --- a/src/board_controller/openbci/ganglion_native.cpp +++ b/src/board_controller/openbci/ganglion_native.cpp @@ -43,6 +43,7 @@ GanglionNative::GanglionNative (struct BrainFlowInputParams params) start_command = "b"; stop_command = "s"; firmware = get_firmware_from_params (params); + current_sampling_rate = Board::get_board_sampling_rate ((int)BrainFlowPresets::DEFAULT_PRESET); } GanglionNative::~GanglionNative () @@ -402,9 +403,22 @@ int GanglionNative::config_board (std::string config) { res = send_command (config); } + if (res == (int)BrainFlowExitCodes::STATUS_OK) + { + track_openbci_sampling_rate (board_id, config, current_sampling_rate); + } return res; } +int GanglionNative::get_board_sampling_rate (int preset) +{ + if (preset != (int)BrainFlowPresets::DEFAULT_PRESET) + { + return Board::get_board_sampling_rate (preset); + } + return current_sampling_rate; +} + int GanglionNative::send_command (std::string config) { if (!initialized) @@ -796,4 +810,4 @@ void GanglionNative::decompress_firmware_2 (const uint8_t *data, double *package eeg_scale * temp_data.last_data[7]; package[board_descr["default"]["timestamp_channel"].get ()] = get_timestamp (); push_package (package); -} \ No newline at end of file +} diff --git a/src/board_controller/openbci/inc/cyton.h b/src/board_controller/openbci/inc/cyton.h index a1f905fa2..957eac0df 100644 --- a/src/board_controller/openbci/inc/cyton.h +++ b/src/board_controller/openbci/inc/cyton.h @@ -11,7 +11,7 @@ class Cyton : public OpenBCISerialBoard protected: CytonGainTracker gain_tracker; - void read_thread (); + void read_thread () override; public: Cyton (struct BrainFlowInputParams params) @@ -19,5 +19,5 @@ class Cyton : public OpenBCISerialBoard { } - int config_board (std::string config, std::string &response); + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/openbci/inc/cyton_daisy.h b/src/board_controller/openbci/inc/cyton_daisy.h index b2b4a7368..4b2476dd2 100644 --- a/src/board_controller/openbci/inc/cyton_daisy.h +++ b/src/board_controller/openbci/inc/cyton_daisy.h @@ -12,7 +12,7 @@ class CytonDaisy : public OpenBCISerialBoard protected: CytonDaisyGainTracker gain_tracker; - void read_thread (); + void read_thread () override; public: CytonDaisy (struct BrainFlowInputParams params) @@ -20,5 +20,5 @@ class CytonDaisy : public OpenBCISerialBoard { } - int config_board (std::string config, std::string &response); + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/openbci/inc/cyton_daisy_wifi.h b/src/board_controller/openbci/inc/cyton_daisy_wifi.h index 4b5c16e84..03780a21a 100644 --- a/src/board_controller/openbci/inc/cyton_daisy_wifi.h +++ b/src/board_controller/openbci/inc/cyton_daisy_wifi.h @@ -11,7 +11,7 @@ class CytonDaisyWifi : public OpenBCIWifiShieldBoard protected: CytonDaisyGainTracker gain_tracker; - void read_thread (); + void read_thread () override; public: // package num, 16 eeg channels, 3 accel channels @@ -20,6 +20,6 @@ class CytonDaisyWifi : public OpenBCIWifiShieldBoard { } - int prepare_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/openbci/inc/cyton_wifi.h b/src/board_controller/openbci/inc/cyton_wifi.h index df559e4d0..0e8b5285a 100644 --- a/src/board_controller/openbci/inc/cyton_wifi.h +++ b/src/board_controller/openbci/inc/cyton_wifi.h @@ -10,7 +10,7 @@ class CytonWifi : public OpenBCIWifiShieldBoard protected: CytonGainTracker gain_tracker; - void read_thread (); + void read_thread () override; public: // package num, 8 eeg channels, 3 accel channels @@ -19,6 +19,6 @@ class CytonWifi : public OpenBCIWifiShieldBoard { } - int prepare_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/openbci/inc/galea.h b/src/board_controller/openbci/inc/galea.h index 47e7362d7..8b76d20d8 100644 --- a/src/board_controller/openbci/inc/galea.h +++ b/src/board_controller/openbci/inc/galea.h @@ -9,6 +9,7 @@ #include "board.h" #include "board_controller.h" #include "openbci_gain_tracker.h" +#include "openbci_sampling_tracker.h" #include "socket_client_udp.h" @@ -26,6 +27,7 @@ class Galea : public Board std::mutex m; std::condition_variable cv; GaleaGainTracker gain_tracker; + int current_sampling_rate; std::string find_device (); void read_thread (); @@ -34,16 +36,17 @@ class Galea : public Board public: Galea (struct BrainFlowInputParams params); - ~Galea (); + ~Galea () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; + int get_board_sampling_rate (int preset) override; static constexpr int package_size = 114; static constexpr int max_num_packages = 25; static constexpr int max_transaction_size = package_size * max_num_packages; static constexpr int socket_timeout = 2; -}; \ No newline at end of file +}; diff --git a/src/board_controller/openbci/inc/ganglion.h b/src/board_controller/openbci/inc/ganglion.h index d9292f550..dd62230b8 100644 --- a/src/board_controller/openbci/inc/ganglion.h +++ b/src/board_controller/openbci/inc/ganglion.h @@ -9,6 +9,7 @@ #include "board_controller.h" #include "data_buffer.h" #include "ganglion_types.h" +#include "openbci_sampling_tracker.h" #include "runtime_dll_loader.h" @@ -25,6 +26,7 @@ class Ganglion : public Board std::string start_command; std::string stop_command; + int current_sampling_rate; volatile bool keep_alive; bool initialized; @@ -55,13 +57,14 @@ class Ganglion : public Board public: Ganglion (struct BrainFlowInputParams params); - ~Ganglion (); - - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + ~Ganglion () override; + + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; + int get_board_sampling_rate (int preset) override; void decompress_firmware_3 (struct GanglionLib::GanglionData *data, float *last_data, double *acceleration, double *package); diff --git a/src/board_controller/openbci/inc/ganglion_native.h b/src/board_controller/openbci/inc/ganglion_native.h index b32a9be34..33f990465 100644 --- a/src/board_controller/openbci/inc/ganglion_native.h +++ b/src/board_controller/openbci/inc/ganglion_native.h @@ -5,6 +5,7 @@ #include "ble_lib_board.h" #include "board.h" #include "board_controller.h" +#include "openbci_sampling_tracker.h" struct GanglionTempData { @@ -82,14 +83,15 @@ class GanglionNative : public BLELibBoard { public: GanglionNative (struct BrainFlowInputParams params); - ~GanglionNative (); + ~GanglionNative () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; int config_board (std::string config); + int get_board_sampling_rate (int preset) override; int send_command (std::string config); void adapter_1_on_scan_start (simpleble_adapter_t adapter); @@ -110,6 +112,7 @@ class GanglionNative : public BLELibBoard std::pair write_characteristics; std::string start_command; std::string stop_command; + int current_sampling_rate; struct GanglionTempData temp_data; double const accel_scale = 0.016f; diff --git a/src/board_controller/openbci/inc/ganglion_wifi.h b/src/board_controller/openbci/inc/ganglion_wifi.h index c1dcede0c..461b951f8 100644 --- a/src/board_controller/openbci/inc/ganglion_wifi.h +++ b/src/board_controller/openbci/inc/ganglion_wifi.h @@ -15,7 +15,7 @@ class GanglionWifi : public OpenBCIWifiShieldBoard volatile bool is_cheking_impedance; protected: - void read_thread (); + void read_thread () override; void read_thread_impedance (); public: @@ -27,7 +27,7 @@ class GanglionWifi : public OpenBCIWifiShieldBoard } // hacks for ganglion and impedance - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int config_board (std::string config, std::string &response); + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/openbci/inc/openbci_sampling_tracker.h b/src/board_controller/openbci/inc/openbci_sampling_tracker.h new file mode 100644 index 000000000..659970a0c --- /dev/null +++ b/src/board_controller/openbci/inc/openbci_sampling_tracker.h @@ -0,0 +1,81 @@ +#pragma once + +#include + +#include "brainflow_constants.h" + +inline int get_openbci_sampling_rate_for_command (int board_id, char command) +{ + switch (static_cast (board_id)) + { + case BoardIds::CYTON_BOARD: + case BoardIds::CYTON_DAISY_BOARD: + case BoardIds::CYTON_WIFI_BOARD: + case BoardIds::CYTON_DAISY_WIFI_BOARD: + case BoardIds::GALEA_BOARD: + switch (command) + { + case '0': + return 16000; + case '1': + return 8000; + case '2': + return 4000; + case '3': + return 2000; + case '4': + return 1000; + case '5': + return 500; + case '6': + return 250; + default: + return -1; + } + case BoardIds::GANGLION_BOARD: + case BoardIds::GANGLION_WIFI_BOARD: + case BoardIds::GANGLION_NATIVE_BOARD: + switch (command) + { + case '0': + return 25600; + case '1': + return 12800; + case '2': + return 6400; + case '3': + return 3200; + case '4': + return 1600; + case '5': + return 800; + case '6': + return 400; + case '7': + return 200; + default: + return -1; + } + default: + return -1; + } +} + +inline bool track_openbci_sampling_rate ( + int board_id, const std::string &config, int &sampling_rate) +{ + for (size_t i = 0; i + 1 < config.size (); i++) + { + if (config[i] != '~') + { + continue; + } + int rate = get_openbci_sampling_rate_for_command (board_id, config[i + 1]); + if (rate > 0) + { + sampling_rate = rate; + return true; + } + } + return false; +} diff --git a/src/board_controller/openbci/inc/openbci_serial_board.h b/src/board_controller/openbci/inc/openbci_serial_board.h index 555c3618d..c556c85ce 100644 --- a/src/board_controller/openbci/inc/openbci_serial_board.h +++ b/src/board_controller/openbci/inc/openbci_serial_board.h @@ -14,6 +14,7 @@ class OpenBCISerialBoard : public Board volatile bool keep_alive; bool initialized; bool is_streaming; + int current_sampling_rate; std::thread streaming_thread; Serial *serial; @@ -28,11 +29,12 @@ class OpenBCISerialBoard : public Board public: OpenBCISerialBoard (struct BrainFlowInputParams params, int board_id); - virtual ~OpenBCISerialBoard (); - - virtual int prepare_session (); - virtual int start_stream (int buffer_size, const char *streamer_params); - virtual int stop_stream (); - virtual int release_session (); - virtual int config_board (std::string config, std::string &response); + ~OpenBCISerialBoard () override; + + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; + int get_board_sampling_rate (int preset) override; }; diff --git a/src/board_controller/openbci/inc/openbci_wifi_shield_board.h b/src/board_controller/openbci/inc/openbci_wifi_shield_board.h index da8997458..ef9da906a 100644 --- a/src/board_controller/openbci/inc/openbci_wifi_shield_board.h +++ b/src/board_controller/openbci/inc/openbci_wifi_shield_board.h @@ -19,6 +19,7 @@ class OpenBCIWifiShieldBoard : public Board volatile bool keep_alive; bool initialized; + int current_sampling_rate; std::thread streaming_thread; SocketServerTCP *server_socket; @@ -30,13 +31,14 @@ class OpenBCIWifiShieldBoard : public Board public: OpenBCIWifiShieldBoard (struct BrainFlowInputParams params, int board_id); - virtual ~OpenBCIWifiShieldBoard (); - - virtual int prepare_session (); - virtual int start_stream (int buffer_size, const char *streamer_params); - virtual int stop_stream (); - virtual int release_session (); - virtual int config_board (std::string config, std::string &response); + ~OpenBCIWifiShieldBoard () override; + + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; + int get_board_sampling_rate (int preset) override; static constexpr int package_size = 33; }; diff --git a/src/board_controller/openbci/openbci_serial_board.cpp b/src/board_controller/openbci/openbci_serial_board.cpp index c41c775c8..c7e6556a4 100644 --- a/src/board_controller/openbci/openbci_serial_board.cpp +++ b/src/board_controller/openbci/openbci_serial_board.cpp @@ -1,5 +1,6 @@ #include +#include "openbci_sampling_tracker.h" #include "openbci_serial_board.h" #include "serial.h" #ifdef _WIN32 @@ -13,6 +14,7 @@ OpenBCISerialBoard::OpenBCISerialBoard (struct BrainFlowInputParams params, int is_streaming = false; keep_alive = false; initialized = false; + current_sampling_rate = Board::get_board_sampling_rate ((int)BrainFlowPresets::DEFAULT_PRESET); } OpenBCISerialBoard::~OpenBCISerialBoard () @@ -62,6 +64,10 @@ int OpenBCISerialBoard::config_board (std::string config, std::string &response) res = send_to_board (config.c_str (), response); } + if (res == (int)BrainFlowExitCodes::STATUS_OK) + { + track_openbci_sampling_rate (board_id, config, current_sampling_rate); + } return res; } @@ -308,3 +314,12 @@ int OpenBCISerialBoard::release_session () } return (int)BrainFlowExitCodes::STATUS_OK; } + +int OpenBCISerialBoard::get_board_sampling_rate (int preset) +{ + if (preset != (int)BrainFlowPresets::DEFAULT_PRESET) + { + return Board::get_board_sampling_rate (preset); + } + return current_sampling_rate; +} diff --git a/src/board_controller/openbci/openbci_wifi_shield_board.cpp b/src/board_controller/openbci/openbci_wifi_shield_board.cpp index f0a0c790f..26079847e 100644 --- a/src/board_controller/openbci/openbci_wifi_shield_board.cpp +++ b/src/board_controller/openbci/openbci_wifi_shield_board.cpp @@ -3,6 +3,7 @@ #include #include +#include "openbci_sampling_tracker.h" #include "openbci_wifi_shield_board.h" #include "socket_client_udp.h" @@ -19,6 +20,7 @@ OpenBCIWifiShieldBoard::OpenBCIWifiShieldBoard (struct BrainFlowInputParams para keep_alive = false; initialized = false; http_timeout = 10; + current_sampling_rate = Board::get_board_sampling_rate ((int)BrainFlowPresets::DEFAULT_PRESET); } OpenBCIWifiShieldBoard::~OpenBCIWifiShieldBoard () @@ -209,6 +211,7 @@ int OpenBCIWifiShieldBoard::send_config (const char *config) "data acquisition thread and device"); } safe_logger (spdlog::level::warn, "If you change gain you may need to rescale EXG data"); + track_openbci_sampling_rate (board_id, std::string (config), current_sampling_rate); return (int)BrainFlowExitCodes::STATUS_OK; } @@ -406,3 +409,12 @@ int OpenBCIWifiShieldBoard::wait_for_http_resp (http_t *request) } return (int)BrainFlowExitCodes::STATUS_OK; } + +int OpenBCIWifiShieldBoard::get_board_sampling_rate (int preset) +{ + if (preset != (int)BrainFlowPresets::DEFAULT_PRESET) + { + return Board::get_board_sampling_rate (preset); + } + return current_sampling_rate; +} diff --git a/src/board_controller/oymotion/inc/gforce_dual.h b/src/board_controller/oymotion/inc/gforce_dual.h index 71daab310..ef796d5d5 100644 --- a/src/board_controller/oymotion/inc/gforce_dual.h +++ b/src/board_controller/oymotion/inc/gforce_dual.h @@ -13,12 +13,12 @@ class GforceDual : public DynLibBoard public: GforceDual (struct BrainFlowInputParams params); - ~GforceDual (); + ~GforceDual () override; - int prepare_session (); + int prepare_session () override; protected: - std::string get_lib_name (); + std::string get_lib_name () override; }; #else @@ -30,13 +30,13 @@ class GforceDual : public Board { public: GforceDual (struct BrainFlowInputParams params); - ~GforceDual (); + ~GforceDual () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; -#endif \ No newline at end of file +#endif diff --git a/src/board_controller/oymotion/inc/gforce_pro.h b/src/board_controller/oymotion/inc/gforce_pro.h index e4e07d8a7..e71a8cbdf 100644 --- a/src/board_controller/oymotion/inc/gforce_pro.h +++ b/src/board_controller/oymotion/inc/gforce_pro.h @@ -13,12 +13,12 @@ class GforcePro : public DynLibBoard public: GforcePro (struct BrainFlowInputParams params); - ~GforcePro (); + ~GforcePro () override; - int prepare_session (); + int prepare_session () override; protected: - std::string get_lib_name (); + std::string get_lib_name () override; }; #else @@ -30,13 +30,13 @@ class GforcePro : public Board { public: GforcePro (struct BrainFlowInputParams params); - ~GforcePro (); + ~GforcePro () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; -#endif \ No newline at end of file +#endif diff --git a/src/board_controller/pieeg/inc/pieeg_board.h b/src/board_controller/pieeg/inc/pieeg_board.h index b6b37b6e6..d5fdfa23c 100644 --- a/src/board_controller/pieeg/inc/pieeg_board.h +++ b/src/board_controller/pieeg/inc/pieeg_board.h @@ -30,11 +30,11 @@ class PIEEGBoard : public Board public: PIEEGBoard (int board_id, struct BrainFlowInputParams params); - ~PIEEGBoard (); + ~PIEEGBoard () override; - int prepare_session (); - int start_stream (int buffer_size, const char *streamer_params); - int stop_stream (); - int release_session (); - int config_board (std::string config, std::string &response); + int prepare_session () override; + int start_stream (int buffer_size, const char *streamer_params) override; + int stop_stream () override; + int release_session () override; + int config_board (std::string config, std::string &response) override; }; diff --git a/src/board_controller/playback_file_board.cpp b/src/board_controller/playback_file_board.cpp index 847d9ad6f..38ea42067 100644 --- a/src/board_controller/playback_file_board.cpp +++ b/src/board_controller/playback_file_board.cpp @@ -132,6 +132,30 @@ int PlaybackFileBoard::start_stream (int buffer_size, const char *streamer_param { return res; } + if (!params.file.empty ()) + { + res = validate_file_access (params.file); + if (res != (int)BrainFlowExitCodes::STATUS_OK) + { + return res; + } + } + if (!params.file_aux.empty ()) + { + res = validate_file_access (params.file_aux); + if (res != (int)BrainFlowExitCodes::STATUS_OK) + { + return res; + } + } + if (!params.file_anc.empty ()) + { + res = validate_file_access (params.file_anc); + if (res != (int)BrainFlowExitCodes::STATUS_OK) + { + return res; + } + } keep_alive = true; if (!params.file.empty ()) @@ -153,6 +177,18 @@ int PlaybackFileBoard::start_stream (int buffer_size, const char *streamer_param return (int)BrainFlowExitCodes::STATUS_OK; } +int PlaybackFileBoard::validate_file_access (const std::string &filename) +{ + FILE *fp = fopen (filename.c_str (), "rb"); + if (fp == NULL) + { + safe_logger (spdlog::level::err, "failed to open file {}", filename); + return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; + } + fclose (fp); + return (int)BrainFlowExitCodes::STATUS_OK; +} + int PlaybackFileBoard::stop_stream () { if (keep_alive) diff --git a/src/board_controller/synchroni/inc/synchroni_board.h b/src/board_controller/synchroni/inc/synchroni_board.h index 97137e2c8..41c69fcc1 100644 --- a/src/board_controller/synchroni/inc/synchroni_board.h +++ b/src/board_controller/synchroni/inc/synchroni_board.h @@ -33,7 +33,7 @@ class SynchroniBoard : public Board public: SynchroniBoard (int board_id, struct BrainFlowInputParams params); - virtual ~SynchroniBoard (); + ~SynchroniBoard () override; int prepare_session () override; int start_stream (int buffer_size, const char *streamer_params) override; diff --git a/src/board_controller/synthetic_board.cpp b/src/board_controller/synthetic_board.cpp index 09be30a02..9677ca130 100644 --- a/src/board_controller/synthetic_board.cpp +++ b/src/board_controller/synthetic_board.cpp @@ -61,8 +61,8 @@ int SyntheticBoard::start_stream (int buffer_size, const char *streamer_params) } keep_alive = true; - streaming_thread = std::thread ([this] { this->read_thread (); }); is_streaming = true; + streaming_thread = std::thread ([this] { this->read_thread (); }); return (int)BrainFlowExitCodes::STATUS_OK; } diff --git a/src/ml/inc/dyn_lib_classifier.h b/src/ml/inc/dyn_lib_classifier.h index f35da5aa5..28a075eff 100644 --- a/src/ml/inc/dyn_lib_classifier.h +++ b/src/ml/inc/dyn_lib_classifier.h @@ -14,15 +14,15 @@ class DynLibClassifier : public BaseClassifier dll_loader = NULL; } - virtual ~DynLibClassifier () + ~DynLibClassifier () override { skip_logs = true; release (); } - virtual int prepare (); - virtual int predict (double *data, int data_len, double *output, int *output_len); - virtual int release (); + int prepare () override; + int predict (double *data, int data_len, double *output, int *output_len) override; + int release () override; protected: virtual std::string get_dyn_lib_path () diff --git a/src/ml/inc/mindfulness_classifier.h b/src/ml/inc/mindfulness_classifier.h index caf2503be..0f6007be5 100644 --- a/src/ml/inc/mindfulness_classifier.h +++ b/src/ml/inc/mindfulness_classifier.h @@ -10,13 +10,13 @@ class MindfulnessClassifier : public BaseClassifier { } - virtual ~MindfulnessClassifier () + ~MindfulnessClassifier () override { skip_logs = true; release (); } - virtual int prepare (); - virtual int predict (double *data, int data_len, double *output, int *output_len); - virtual int release (); -}; \ No newline at end of file + int prepare () override; + int predict (double *data, int data_len, double *output, int *output_len) override; + int release () override; +}; diff --git a/src/ml/inc/restfulness_classifier.h b/src/ml/inc/restfulness_classifier.h index 69e22734a..dcfa9252f 100644 --- a/src/ml/inc/restfulness_classifier.h +++ b/src/ml/inc/restfulness_classifier.h @@ -11,7 +11,7 @@ class RestfulnessClassifier : public MindfulnessClassifier { } - int predict (double *data, int data_len, double *output, int *output_len) + int predict (double *data, int data_len, double *output, int *output_len) override { int res = MindfulnessClassifier::predict (data, data_len, output, output_len); if (res != (int)BrainFlowExitCodes::STATUS_OK) @@ -21,4 +21,4 @@ class RestfulnessClassifier : public MindfulnessClassifier *output = 1.0 - (*output); return res; } -}; \ No newline at end of file +}; diff --git a/src/ml/onnx/inc/onnx_classifier.h b/src/ml/onnx/inc/onnx_classifier.h index c4f3814ce..18b8cc216 100644 --- a/src/ml/onnx/inc/onnx_classifier.h +++ b/src/ml/onnx/inc/onnx_classifier.h @@ -45,13 +45,13 @@ class OnnxClassifier : public BaseClassifier dll_loader = NULL; } - ~OnnxClassifier () + ~OnnxClassifier () override { skip_logs = true; release (); } - int prepare (); - int predict (double *data, int data_len, double *output, int *output_len); - int release (); + int prepare () override; + int predict (double *data, int data_len, double *output, int *output_len) override; + int release () override; }; diff --git a/src/ml/onnx/onnx_classifier.cpp b/src/ml/onnx/onnx_classifier.cpp index c168ecce9..02d99724b 100644 --- a/src/ml/onnx/onnx_classifier.cpp +++ b/src/ml/onnx/onnx_classifier.cpp @@ -364,7 +364,7 @@ int OnnxClassifier::predict (double *data, int data_len, double *output, int *ou default: { safe_logger (spdlog::level::err, "unknown output type"); - res = (int)BrainFlowExitCodes::STATUS_OK; + res = (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; } } } @@ -387,7 +387,7 @@ int OnnxClassifier::predict (double *data, int data_len, double *output, int *ou delete[] float_data; } - return (int)BrainFlowExitCodes::STATUS_OK; + return res; } int OnnxClassifier::release () @@ -887,4 +887,4 @@ int OnnxClassifier::get_output_info () } return res; -} \ No newline at end of file +}