| 396 | } |
| 397 | |
| 398 | void Explore::parse_eeg_data (const ExploreHeader *header, double *package, unsigned char *payload, |
| 399 | double vref, int n_packages) |
| 400 | { |
| 401 | int payload_size = header->payload_size; |
| 402 | if ((payload[payload_size - 4] != 0xAF) || (payload[payload_size - 3] != 0xBE) || |
| 403 | (payload[payload_size - 2] != 0xAD) || (payload[payload_size - 1] != 0xDE)) |
| 404 | { |
| 405 | safe_logger (spdlog::level::warn, "checksum failed, {} {} {} {}", payload[payload_size - 4], |
| 406 | payload[payload_size - 3], payload[payload_size - 2], payload[payload_size - 1]); |
| 407 | return; |
| 408 | } |
| 409 | double current_timestamp = get_timestamp (); |
| 410 | payload_size = payload_size - 4; |
| 411 | std::vector<int> eeg_channels = board_descr["default"]["eeg_channels"]; |
| 412 | if ((payload_size % n_packages != 0) || (payload_size % 3 != 0)) // 3 is int24 format |
| 413 | { |
| 414 | safe_logger (spdlog::level::warn, |
| 415 | "Invalid payload size for EEG package: {}, n_packages: {}", payload_size, n_packages); |
| 416 | return; |
| 417 | } |
| 418 | if (payload_size % (eeg_channels.size () + 1) != 0) // 1 for data status, maybe its reference |
| 419 | { |
| 420 | safe_logger (spdlog::level::warn, "Invalid payload size for num_eeg_channels: {}, {}", |
| 421 | payload_size, eeg_channels.size ()); |
| 422 | return; |
| 423 | } |
| 424 | |
| 425 | int num_datapoints = payload_size / 3; |
| 426 | // convert to uV |
| 427 | std::vector<double> data; |
| 428 | for (int i = 0; i < num_datapoints; i++) |
| 429 | { |
| 430 | double datapoint = |
| 431 | (double)cast_24bit_to_int32_swap_order ((unsigned char *)(payload + i * 3)); |
| 432 | data.push_back (datapoint); |
| 433 | } |
| 434 | int num_total_channels = (int)eeg_channels.size () + 1; |
| 435 | int other_channel = board_descr["default"]["other_channels"][0]; |
| 436 | // submit packages |
| 437 | if (last_eeg_timestamp > 0.0) |
| 438 | { |
| 439 | double step = (current_timestamp - last_eeg_timestamp) / n_packages; |
| 440 | for (int i = 0; i < n_packages; i++) |
| 441 | { |
| 442 | for (int j = 0; j < num_total_channels; j++) |
| 443 | { |
| 444 | if (j == 0) |
| 445 | { |
| 446 | package[other_channel] = data[i * num_total_channels + j]; |
| 447 | } |
| 448 | else |
| 449 | { |
| 450 | double gain = 1.E-6 * (pow (2, 23) - 1) * 6.0; |
| 451 | package[eeg_channels[j - 1]] = data[i * num_total_channels + j] * vref / gain; |
| 452 | } |
| 453 | } |
| 454 | package[board_descr["default"]["timestamp_channel"].get<int> ()] = last_eeg_timestamp + |
| 455 | step * (i + 1); // todo improve timestamps, use data from device |
nothing calls this directly
no test coverage detected