Skip to content
Snippets Groups Projects
Commit 9db582a3 authored by Tim Übelhör's avatar Tim Übelhör
Browse files

Lots of fixes

parent b3c94eb6
Branches
No related tags found
No related merge requests found
......@@ -11,14 +11,28 @@ ADIDatCli::AdiDatWriter::AdiDatWriter(String ^ path, IEnumerable<String^>^ chann
// Create the native vectors
std::vector<std::string> vecChannelNames;
for each(auto name in channelNames)
{
if (name == nullptr)
{
vecChannelNames.push_back("no name");
}
else
{
vecChannelNames.push_back(marshal_as<std::string>(name));
}
}
std::vector<std::string> vecChannelUnits;
for each(auto unit in channelUnits)
{
if (unit == nullptr)
{
vecChannelUnits.push_back("no unit");
}
else
{
vecChannelUnits.push_back(marshal_as<std::string>(unit));
}
}
// Check conistency
if (vecChannelNames.size() != vecChannelUnits.size())
{
......@@ -34,8 +48,19 @@ ADIDatCli::AdiDatWriter::~AdiDatWriter()
delete(_writer);
}
void ADIDatCli::AdiDatWriter::AppendData(IEnumerable<IEnumerable<float>^>^ data)
void ADIDatCli::AdiDatWriter::AddRecord(IEnumerable<IEnumerable<float>^>^ data)
{
std::vector<std::vector<float>> dataVector;
// Copy the data into c++ vecors
for each(auto channel in data)
{
throw gcnew System::NotImplementedException();
std::vector<float> samples;
for each(float sample in channel)
{
samples.push_back(sample);
}
dataVector.push_back(samples);
}
_writer->AddRecord(dataVector);
}
......@@ -15,7 +15,10 @@ namespace ADIDatCli
/// Creates the file in the path. Also set up the
AdiDatWriter(String^ path, IEnumerable<String^>^ channelNames, IEnumerable<String^>^ channelUnits, double secondsPerSample);
~AdiDatWriter();
void AppendData( IEnumerable<IEnumerable<float>^>^ data);
/// Adds a new record to the file
void AddRecord(
IEnumerable<IEnumerable<float>^>^ data // An enumerable of channel data. Each inner enumerable must have the same size.
);
private:
// The native class does the actual work
NativeWriter* _writer;
......
......@@ -21,7 +21,7 @@
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{080112AF-3D1C-4269-BA88-3AD5E0C5F587}</ProjectGuid>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<Keyword>ManagedCProj</Keyword>
<RootNamespace>AdidatCLI</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
......
#include "stdafx.h"
#include "NativeWriter.h"
#include <ctime>
#include "ADIDatCAPI.h"
NativeWriter::NativeWriter(std::string path, std::vector<std::string> channelNames, std::vector<std::string> channelUnits, double secondsPerSample)
NativeWriter::NativeWriter(std::string path, std::vector<std::string> channelNames, std::vector<std::string> channelUnits, double secondsPerSample) :
_fileHandle(0), _writerHandle(0)
{
_channelCount = channelNames.size();
if (_channelCount > 32)
{
throw new std::invalid_argument("Only a maximum of 32 channels is supported by the LabView data export.");
}
// Create the file
_path = std::wstring(path.length(), L'\0');
size_t pathCharsConverted = 0;
mbstowcs_s(&pathCharsConverted, &_path[0], path.length(), path.c_str(), _path.length());
ADI_FileHandle fileHandle(0);
checkResult(ADI_CreateFile(_path.c_str(), &fileHandle));
std::wstring wPath(path.begin(), path.end());
checkResult(ADI_CreateFile(wPath.c_str(), &_fileHandle));
// Start writing
ADI_WriterHandle writerHandle(0);
checkResult(ADI_CreateWriter(fileHandle, &writerHandle));
checkResult(ADI_CreateWriter(_fileHandle, &_writerHandle));
// Set the channels names and indo
for (int channel = 0; channel < static_cast<int>(channelNames.size()); channel++)
for (size_t channel = 0; channel < channelNames.size(); channel++)
{
std::wstring wName(channelNames[channel].size(), L'\0');
size_t channelCharsConverted = 0;
mbstowcs_s(&channelCharsConverted, &wName[0], channelNames[channel].length(), channelNames[channel].c_str(), wName.length());
ADI_SetChannelName(fileHandle, channel, wName.c_str());
std::wstring wUnit(channelUnits[channel].size(), L'\0');
size_t unitCharsConverted = 0;
mbstowcs_s(&unitCharsConverted, &wUnit[0], channelUnits[channel].length(), channelUnits[channel].c_str(), wUnit.length());
checkResult(ADI_SetChannelInfo(writerHandle, channel, true, secondsPerSample, wUnit.c_str(), NULL));
std::wstring wName(channelNames[channel].begin(), channelNames[channel].end());
checkResult(ADI_SetChannelName(_fileHandle, static_cast<long>(channel), wName.c_str()));
std::wstring wUnit(channelUnits[channel].begin(), channelUnits[channel].end());
checkResult(ADI_SetChannelInfo(_writerHandle, static_cast<long>(channel), true, secondsPerSample, wUnit.c_str(), NULL));
}
// Commit the changes
checkResult(ADI_CommitFile(writerHandle, 0));
checkResult(ADI_CloseWriter(&writerHandle));
checkResult(ADI_CloseFile(&fileHandle));
}
NativeWriter::~NativeWriter()
{
// Close the file
checkResult(ADI_CloseWriter(&_writerHandle));
checkResult(ADI_CloseFile(&_fileHandle));
}
void NativeWriter::checkResult(int code)
......@@ -57,34 +52,22 @@ void NativeWriter::checkResult(int code)
// If it is kResultsuccess we are all fine :)
}
void NativeWriter::AppendData(std::vector<std::vector<float>> data)
{
// Check if the data is consistent
if (data.empty())
void NativeWriter::AddRecord(std::vector<std::vector<float>> data)
{
return;
}
size_t samplesToAdd = data[0].size();
// Determine how many samples we can add
size_t samplesToAdd = SIZE_MAX;
for (auto channel : data)
{
if (channel.size() != samplesToAdd)
if (channel.size() < samplesToAdd)
{
throw new std::invalid_argument("The channels do no contain an equal number of samples.");
samplesToAdd = channel.size();
}
}
// Open the file
ADI_FileHandle fileHandle(0);
checkResult(ADI_OpenFile(_path.c_str(), &fileHandle, ADIFileOpenMode::kOpenFileForReadAndWrite));
// Create the write handler
ADI_WriterHandle writerHandle(0);
checkResult(ADI_CreateWriter(fileHandle, &writerHandle));
// Start a new record
time_t currentTime;
time(&currentTime);
checkResult(ADI_StartRecord(writerHandle, currentTime, 0, 0));
checkResult(ADI_StartRecord(_writerHandle, currentTime, 0, 0));
// Add chunks of samples parallel for all channels
// Add the data to the record
size_t samplesAdded = 0;
while (samplesAdded < samplesToAdd)
......@@ -95,18 +78,18 @@ void NativeWriter::AppendData(std::vector<std::vector<float>> data)
{
chunkSize = OPTIMAL_CHUNK_SIZE;
}
long samplesAdded = 0;
for (int i = 0; i < static_cast<int>(data.size()); i++)
for (size_t channel = 0; channel < data.size(); channel++)
{
// Add the data directly from the matrix
checkResult(ADI_AddChannelSamples(writerHandle, i, &data[i][samplesAdded], chunkSize, &samplesAdded));
// Write it
long writtenSamples = 0;
checkResult(ADI_AddChannelSamples(_writerHandle, static_cast<long>(channel), data[channel].data() + samplesAdded, chunkSize, &writtenSamples));
// Weird but once the chunk is written to the first channel, all other channels will retunr writtenSamples = 0 :(
samplesAdded += writtenSamples;
}
}
// Close the record
checkResult(ADI_FinishRecord(writerHandle));
checkResult(ADI_FinishRecord(_writerHandle));
// Commit the changes
checkResult(ADI_CommitFile(writerHandle, 0));
checkResult(ADI_CloseWriter(&writerHandle));
checkResult(ADI_CloseFile(&fileHandle));
checkResult(ADI_CommitFile(_writerHandle, 0));
}
\ No newline at end of file
#pragma once
#include <string>
#include <vector>
#include "ADIDatCAPI.h"
// For best display in labchart
const size_t OPTIMAL_CHUNK_SIZE = 16000;
// For best display in labchart medium size chunks
const long OPTIMAL_CHUNK_SIZE = 1024;
// The maximal count of characters when getting the error message
const size_t MAX_ERROR_MESSAGE_SIZE = 1024;
class NativeWriter
{
private:
// Where we created the file
std::wstring _path;
// Handles for the file and writer
// Must stay open otherwise writing fails ?!
ADI_FileHandle _fileHandle;
ADI_WriterHandle _writerHandle;
// Rememebr how many channels we use
size_t _channelCount;
/// Throws an exception if any error occured
void checkResult(int code);
public:
NativeWriter(std::string path, std::vector<std::string> channelNames, std::vector<std::string> channelUnits, double secondsPerSample);
void AppendData(std::vector<std::vector<float>> data);
void AddRecord(std::vector<std::vector<float>> data);
~NativeWriter();
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment