feat: the export writes an MDF 3.30 file, so a window loads in ScryLab
A third format beside `.npy` and `.csv`, written by hand in `src/export.cpp` -- MF4 is HDF5 and would mean a library, MF3 is a handful of fixed blocks. The layout is the asammdf 8.8.27 reader's own field list, byte-diffed against a known-good 3.30 file it wrote; the shape is the one ScryLab's data-source contract asks for: one channel group, record-interleaved, the master as the x axis, and the unit in the channel's conversion block. So in MDF the master is `abs_seconds`, named `time` -- the clock that is the same in every display mode -- and the plotted axis goes out as an ordinary channel, `time_relative`. `ExportTable::Column` gained the CONFIG's unit, which only this writer spells out; the `.npy`/`.csv` bytes are unchanged, and `write_export()` now picks the writer for both the dialog and the probe.
This commit is contained in:
1 parent
761615c2fe
commit
908286ee89
10 files changed
+505
-28
No files matched your search
+14
-3
@@ -2345,11 +2345,10 @@ gboolean export_probe(gpointer user) {
|
||||
std::fprintf(stderr, "[export-probe] column '%s' n=%zu\n", col.name.c_str(), col.values.size());
|
||||
}
|
||||
|
||||
for (const char* ext : {".npy", ".csv"}) {
|
||||
for (const char* ext : {".npy", ".csv", ".mf3"}) {
|
||||
const std::string path = prefix + ext;
|
||||
std::string error;
|
||||
const bool ok = std::strcmp(ext, ".csv") == 0 ? write_csv(path, table, error)
|
||||
: write_npy(path, table, error);
|
||||
const bool ok = write_export(path, table, error);
|
||||
long bytes = -1;
|
||||
if (ok) {
|
||||
if (std::FILE* f = std::fopen(path.c_str(), "rb"); f != nullptr) {
|
||||
@@ -2361,6 +2360,18 @@ gboolean export_probe(gpointer user) {
|
||||
std::fprintf(stderr, "[export-probe] %s %s bytes=%ld%s%s\n", path.c_str(),
|
||||
ok ? "written" : "FAILED", bytes, ok ? "" : " error=", ok ? "" : error.c_str());
|
||||
}
|
||||
// What the `.mf3` was handed, in the shape the file stores it: the master and the relative
|
||||
// axis are channels too, and `record` is the bytes of one interleaved record. So the size the
|
||||
// line above printed is `272 + comment + rows*record + 28 + channels*274 + 30`, and the units
|
||||
// are the ones ScryLab reads each signal's unit from -- the CONFIG's, per column.
|
||||
std::string units;
|
||||
for (const char* u : {"s", "s"}) units += std::string(units.empty() ? "" : " ") + "'" + u + "'";
|
||||
for (const ExportTable::Column& col : table.columns) {
|
||||
units += std::string(units.empty() ? "" : " ") + "'" + col.unit + "'";
|
||||
}
|
||||
std::fprintf(stderr,
|
||||
"[export-probe] mdf master=time master_unit=s channels=%zu record=%zu units=[%s]\n",
|
||||
table.columns.size() + 2, 16 + 4 * table.columns.size(), units.c_str());
|
||||
std::fflush(stderr);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user