Files
XYParser/XYParser/XYParserApi.cpp
2026-06-06 10:07:53 +08:00

155 lines
4.8 KiB
C++

#include "pch.h"
#include "XYParserApi.h"
#include "XYEegParser8.h"
#include "XYEegParser64.h"
#include <algorithm>
#include <new>
#include <string>
#include <vector>
namespace {
struct ParserContext {
std::uint8_t channel_count = 0;
XYEegParser8 parser8;
XYEegParser64 parser64;
std::string last_error;
};
void FillSummary(const XYEegFrame8& frame, XYParserFrameSummary& summary)
{
summary.frame_index = frame.index;
summary.channel_count = frame.channel_count;
summary.battery = frame.battery;
summary.sample_count = static_cast<std::uint8_t>(frame.samples.size());
for (std::size_t sample_index = 0; sample_index < XYPARSER_SAMPLES_PER_FRAME; ++sample_index) {
summary.trigger_types[sample_index] = frame.samples[sample_index].trigger_type;
summary.trigger_indices[sample_index] = frame.samples[sample_index].trigger_index;
for (std::size_t channel_index = 0; channel_index < XYPARSER_MAX_CHANNELS; ++channel_index) {
summary.channel_values_uv[sample_index][channel_index] =
channel_index < frame.channel_count
? frame.samples[sample_index].channel_values_uv[channel_index]
: 0.0;
}
}
}
void FillSummary(const XYEegFrame64& frame, XYParserFrameSummary& summary)
{
summary.frame_index = frame.index;
summary.channel_count = frame.channel_count;
summary.battery = frame.battery;
summary.sample_count = static_cast<std::uint8_t>(frame.samples.size());
for (std::size_t sample_index = 0; sample_index < XYPARSER_SAMPLES_PER_FRAME; ++sample_index) {
summary.trigger_types[sample_index] = frame.samples[sample_index].trigger_type;
summary.trigger_indices[sample_index] = frame.samples[sample_index].trigger_index;
for (std::size_t channel_index = 0; channel_index < XYPARSER_MAX_CHANNELS; ++channel_index) {
summary.channel_values_uv[sample_index][channel_index] =
channel_index < frame.channel_count
? frame.samples[sample_index].channel_values_uv[channel_index]
: 0.0;
}
}
}
} // namespace
extern "C" {
XYParserHandle XYParser_CreateParser(std::uint8_t channel_count)
{
if (channel_count != 8 && channel_count != 64) {
return nullptr;
}
ParserContext* context = new (std::nothrow) ParserContext();
if (context == nullptr) {
return nullptr;
}
context->channel_count = channel_count;
return context;
}
void XYParser_DestroyParser(XYParserHandle handle)
{
ParserContext* context = static_cast<ParserContext*>(handle);
delete context;
}
void XYParser_SetAdcParams(XYParserHandle handle, double vref, double gain)
{
ParserContext* context = static_cast<ParserContext*>(handle);
if (context == nullptr) {
return;
}
if (context->channel_count == 8) {
context->parser8.SetAdcParams(vref, gain);
} else {
context->parser64.SetAdcParams(vref, gain);
}
}
void XYParser_SetBypassChecksum(XYParserHandle handle, int bypass)
{
ParserContext* context = static_cast<ParserContext*>(handle);
if (context == nullptr) {
return;
}
const bool enabled = bypass != 0;
if (context->channel_count == 8) {
context->parser8.SetBypassChecksum(enabled);
} else {
context->parser64.SetBypassChecksum(enabled);
}
}
int XYParser_Feed(XYParserHandle handle,
const std::uint8_t* data,
std::size_t size,
XYParserFrameSummary* out_summaries,
int max_summaries)
{
ParserContext* context = static_cast<ParserContext*>(handle);
if (context == nullptr || data == nullptr || size == 0) {
return 0;
}
if (max_summaries < 0) {
max_summaries = 0;
}
if (context->channel_count == 8) {
const std::vector<XYEegFrame8> frames = context->parser8.Feed(data, size);
context->last_error = context->parser8.LastError();
const int write_count = std::min<int>(static_cast<int>(frames.size()), max_summaries);
for (int i = 0; i < write_count; ++i) {
FillSummary(frames[static_cast<std::size_t>(i)], out_summaries[i]);
}
return write_count;
}
const std::vector<XYEegFrame64> frames = context->parser64.Feed(data, size);
context->last_error = context->parser64.LastError();
const int write_count = std::min<int>(static_cast<int>(frames.size()), max_summaries);
for (int i = 0; i < write_count; ++i) {
FillSummary(frames[static_cast<std::size_t>(i)], out_summaries[i]);
}
return write_count;
}
const char* XYParser_GetLastError(XYParserHandle handle)
{
ParserContext* context = static_cast<ParserContext*>(handle);
if (context == nullptr) {
return "invalid parser handle";
}
return context->last_error.c_str();
}
}