Commit 48afa476 authored by Jussi Lindgren's avatar Jussi Lindgren Committed by Serrière Guillaume

Plugins: Misc fixes to the TCP writer box

- Fixed handling of 1-dimensional matrices in TCPWriter
- Removed all transposes of the outputs in TCPWriter
- Removed incorrect setting modify flag in TCPWriter
- Fixed the example client buffersize to chunk size to reduce delays with tiny chunks
- Changed the example client to allow reading either stim, signal or both, and write signal to file
- Minor code cleanup
parent 0a38e128
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier> <Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x02017c54)</Value> <Value>(0x00000000, 0x015d7484)</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier> <Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
...@@ -68,6 +68,79 @@ ...@@ -68,6 +68,79 @@
</Attribute> </Attribute>
</Attributes> </Attributes>
</Box> </Box>
<Box>
<Identifier>(0x00002e3e, 0x00002059)</Identifier>
<Name>Stimuli to TCP</Name>
<AlgorithmClassIdentifier>(0x02f24947, 0x17fa0477)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input 1</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Port</Name>
<DefaultValue>5678</DefaultValue>
<Value>5679</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x6d7e53dd, 0x6a0a4753)</TypeIdentifier>
<Name>Stimulus output</Name>
<DefaultValue>Raw</DefaultValue>
<Value>String</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>400.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>53</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>480.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xd1b2ff20, 0x919e4441)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>100</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x016b97f3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box> <Box>
<Identifier>(0x0000360b, 0x0000614e)</Identifier> <Identifier>(0x0000360b, 0x0000614e)</Identifier>
<Name>Signal display</Name> <Name>Signal display</Name>
...@@ -178,7 +251,7 @@ ...@@ -178,7 +251,7 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier> <Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x033e3986)</Value> <Value>(0x00000000, 0x01e683c6)</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier> <Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
...@@ -236,7 +309,7 @@ ...@@ -236,7 +309,7 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier> <Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x02dff832)</Value> <Value>(0x00000000, 0x01b4ded6)</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier> <Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
...@@ -249,7 +322,7 @@ ...@@ -249,7 +322,7 @@
</Attributes> </Attributes>
</Box> </Box>
<Box> <Box>
<Identifier>(0x00004e8d, 0x00003806)</Identifier> <Identifier>(0x000054a6, 0x00001c9c)</Identifier>
<Name>Signal to TCP</Name> <Name>Signal to TCP</Name>
<AlgorithmClassIdentifier>(0x02f24947, 0x17fa0477)</AlgorithmClassIdentifier> <AlgorithmClassIdentifier>(0x02f24947, 0x17fa0477)</AlgorithmClassIdentifier>
<Inputs> <Inputs>
...@@ -267,7 +340,7 @@ ...@@ -267,7 +340,7 @@
<Modifiability>false</Modifiability> <Modifiability>false</Modifiability>
</Setting> </Setting>
<Setting> <Setting>
<TypeIdentifier>(0x6d7e53dd, 0x6a0a4753)</TypeIdentifier> <TypeIdentifier>(0x77d3e238, 0xb954ec48)</TypeIdentifier>
<Name>Stimulus output</Name> <Name>Stimulus output</Name>
<DefaultValue>Raw</DefaultValue> <DefaultValue>Raw</DefaultValue>
<Value>Raw</Value> <Value>Raw</Value>
...@@ -289,7 +362,7 @@ ...@@ -289,7 +362,7 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier> <Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb3ff8941, 0x4943ae4b)</Value> <Value>(0xd1b2ff20, 0x919e4441)</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier> <Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
...@@ -301,80 +374,7 @@ ...@@ -301,80 +374,7 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier> <Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x019d6582)</Value> <Value>(0x00000000, 0x00dda356)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xf191c1c8, 0xa0123976)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00005ae2, 0x000004fd)</Identifier>
<Name>Stimuli to TCP</Name>
<AlgorithmClassIdentifier>(0x02f24947, 0x17fa0477)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input 1</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Port</Name>
<DefaultValue>5678</DefaultValue>
<Value>5679</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x6d7e53dd, 0x6a0a4753)</TypeIdentifier>
<Name>Stimulus output</Name>
<DefaultValue>Raw</DefaultValue>
<Value>String</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>400.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>53</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>480.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb3ff8941, 0x4943ae4b)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>100</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x027c9cc4)</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier> <Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
...@@ -388,23 +388,19 @@ ...@@ -388,23 +388,19 @@
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier> <Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value> <Value>1</Value>
</Attribute> </Attribute>
<Attribute>
<Identifier>(0xf191c1c8, 0xa0123976)</Identifier>
<Value></Value>
</Attribute>
</Attributes> </Attributes>
</Box> </Box>
</Boxes> </Boxes>
<Links> <Links>
<Link> <Link>
<Identifier>(0x000027e0, 0x00000a8f)</Identifier> <Identifier>(0x0000169e, 0x000043c2)</Identifier>
<Source> <Source>
<BoxIdentifier>(0x000047dd, 0x00002575)</BoxIdentifier> <BoxIdentifier>(0x00002055, 0x00006c8d)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex> <BoxOutputIndex>0</BoxOutputIndex>
</Source> </Source>
<Target> <Target>
<BoxIdentifier>(0x0000360b, 0x0000614e)</BoxIdentifier> <BoxIdentifier>(0x000054a6, 0x00001c9c)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex> <BoxInputIndex>0</BoxInputIndex>
</Target> </Target>
<Attributes> <Attributes>
<Attribute> <Attribute>
...@@ -413,26 +409,26 @@ ...@@ -413,26 +409,26 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier> <Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>448</Value> <Value>224</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier> <Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>283</Value> <Value>369</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier> <Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>352</Value> <Value>208</Value>
</Attribute> </Attribute>
</Attributes> </Attributes>
</Link> </Link>
<Link> <Link>
<Identifier>(0x0000384a, 0x00007419)</Identifier> <Identifier>(0x00002314, 0x00004bab)</Identifier>
<Source> <Source>
<BoxIdentifier>(0x000047dd, 0x00002575)</BoxIdentifier> <BoxIdentifier>(0x000047dd, 0x00002575)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex> <BoxOutputIndex>0</BoxOutputIndex>
</Source> </Source>
<Target> <Target>
<BoxIdentifier>(0x00005ae2, 0x000004fd)</BoxIdentifier> <BoxIdentifier>(0x00002e3e, 0x00002059)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex> <BoxInputIndex>0</BoxInputIndex>
</Target> </Target>
<Attributes> <Attributes>
...@@ -455,14 +451,14 @@ ...@@ -455,14 +451,14 @@
</Attributes> </Attributes>
</Link> </Link>
<Link> <Link>
<Identifier>(0x00005f85, 0x00005a35)</Identifier> <Identifier>(0x000027e0, 0x00000a8f)</Identifier>
<Source> <Source>
<BoxIdentifier>(0x00002055, 0x00006c8d)</BoxIdentifier> <BoxIdentifier>(0x000047dd, 0x00002575)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex> <BoxOutputIndex>0</BoxOutputIndex>
</Source> </Source>
<Target> <Target>
<BoxIdentifier>(0x00004e8d, 0x00003806)</BoxIdentifier> <BoxIdentifier>(0x0000360b, 0x0000614e)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex> <BoxInputIndex>1</BoxInputIndex>
</Target> </Target>
<Attributes> <Attributes>
<Attribute> <Attribute>
...@@ -471,15 +467,15 @@ ...@@ -471,15 +467,15 @@
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier> <Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>224</Value> <Value>448</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier> <Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>369</Value> <Value>283</Value>
</Attribute> </Attribute>
<Attribute> <Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier> <Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>208</Value> <Value>352</Value>
</Attribute> </Attribute>
</Attributes> </Attributes>
</Link> </Link>
......
/* /*
* Receives data from two OpenViBE TCPWriter boxes, a signal writer and a stimulus writer. * Receives data from one or two OpenViBE TCPWriter boxes, a signal writer and a stimulus writer.
* *
* The code reads the two corresponding sockets asynchronously. With signal, the header contents * The code reads the two corresponding sockets asynchronously. With signal, the header contents
* are printed first. Next, every time a stimulus is received, the code will print out the stimulus * are printed first. If a stimulus is received, the code will print out the stimulus
* and how many bytes of signal have been read and discarded the meanwhile. In order not to make this * and how many bytes of signal have been read the meanwhile. In order not to make this
* code more complicated by mutexes, the signal thread does not try to print anything to cout but just * code more complicated by mutexes, the signal thread does not try to print anything to cout.
* discards the data. * Instead, it either discards the data or writes it to a file (if name has been given)
* *
* This code is meant to be used with the corresponding scenario 'tcpwriter.xml' * This code is meant to be used with the corresponding scenario 'tcpwriter.xml'
* *
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#ifdef TARGET_HAS_Boost #ifdef TARGET_HAS_Boost
#include <iostream> #include <iostream>
#include <fstream>
#include <cstdlib> #include <cstdlib>
#include <boost/array.hpp> #include <boost/array.hpp>
...@@ -31,50 +32,73 @@ using boost::asio::ip::tcp; ...@@ -31,50 +32,73 @@ using boost::asio::ip::tcp;
*/ */
class TCPWriterClient { class TCPWriterClient {
public: public:
TCPWriterClient(boost::asio::io_service& ioService, const char* sAddress, const char* sSignalPort, const char* sStimulusPort) : ~TCPWriterClient()
stimulusSocket(ioService), {
signalSocket(ioService), if(m_dataFile.is_open()) {
signalBytesRead(0) m_dataFile.close();
}
}
TCPWriterClient(boost::asio::io_service& ioService, const char* sAddress, const char* sSignalPort, const char* sStimulusPort,
const char* sDataFilename) :
m_stimulusSocket(ioService),
m_signalSocket(ioService),
m_signalBytesRead(0)
{ {
boost::system::error_code error; boost::system::error_code error;
tcp::resolver resolver(ioService); tcp::resolver resolver(ioService);
// Signal port if(sDataFilename) {
std::cout << "Connecting to signal port [" << sAddress << " : " << sSignalPort << "]\n"; m_dataFile.open(sDataFilename, std::ios::binary|std::ios::trunc|std::ios::out);
tcp::resolver::query query = tcp::resolver::query(tcp::v4(), sAddress, sSignalPort); }
signalSocket.connect(*resolver.resolve(query), error);
if(sStimulusPort && strcmp(sStimulusPort,"0")!=0)
// Stimulus port {
std::cout << "Connecting to stimulus port [" << sAddress << " : " << sStimulusPort << "]\n"; // Stimulus port
query = tcp::resolver::query(tcp::v4(), sAddress, sStimulusPort); std::cout << "Connecting to stimulus port [" << sAddress << " : " << sStimulusPort << "]\n";
stimulusSocket.connect(*resolver.resolve(query), error); tcp::resolver::query query = tcp::resolver::query(tcp::v4(), sAddress, sStimulusPort);
m_stimulusSocket.connect(*resolver.resolve(query), error);
// Tell ASIO to read a stimulus
boost::asio::async_read_until(m_stimulusSocket, m_stimulusStream, "\n",
boost::bind(&TCPWriterClient::stimulusHandler, this,
boost::asio::placeholders::error));
}
// Tell ASIO to read a stimulus if(sSignalPort && strcmp(sSignalPort,"0")!=0)
boost::asio::async_read_until(stimulusSocket, stimulusStream, "\n", {
boost::bind(&TCPWriterClient::stimulusHandler, this, // Signal port
std::cout << "Connecting to signal port [" << sAddress << " : " << sSignalPort << "]\n";
tcp::resolver::query query = tcp::resolver::query(tcp::v4(), sAddress, sSignalPort);
m_signalSocket.connect(*resolver.resolve(query), error);
boost::asio::ip::tcp::no_delay l_oNoDelay(true);
m_signalSocket.set_option(l_oNoDelay);
// Tell ASIO to read the signal header
boost::asio::async_read(m_signalSocket, boost::asio::buffer(m_signalHeaderBuffer.data(), m_headerSize),
boost::asio::transfer_at_least(m_headerSize),
boost::bind(&TCPWriterClient::signalHeaderHandler, this,
boost::asio::placeholders::error)); boost::asio::placeholders::error));
}
// Tell ASIO to read the signal header
boost::asio::async_read(signalSocket, boost::asio::buffer(signalBuffer.data(), bufferSize),
boost::asio::transfer_at_least(headerSize),
boost::bind(&TCPWriterClient::signalHeaderHandler, this,
boost::asio::placeholders::error));
} }
tcp::socket stimulusSocket; tcp::socket m_stimulusSocket;
tcp::socket signalSocket; tcp::socket m_signalSocket;
static const int headerSize = 32; // signal header size static const int m_headerSize = 32; // signal header size
static const int bufferSize = 1024; // signal buffer size int m_bufferSize; // signal buffer size
boost::array<char, headerSize> signalHeaderBuffer; boost::array<char, m_headerSize> m_signalHeaderBuffer;
boost::array<char, bufferSize> signalBuffer; std::vector<char> m_signalBuffer;
unsigned long long signalBytesRead; // how many bytes of signal read so far unsigned long long m_signalBytesRead; // how many bytes of signal read so far
boost::asio::streambuf stimulusStream; boost::asio::streambuf m_stimulusStream;
std::ofstream m_dataFile;
void stimulusHandler(const boost::system::error_code& error) void stimulusHandler(const boost::system::error_code& error)
{ {
...@@ -84,10 +108,10 @@ public: ...@@ -84,10 +108,10 @@ public:
throw boost::system::system_error(error); // Some other error. throw boost::system::system_error(error); // Some other error.
// std::cout.write(stimulusBuffer.data(), strlen(stimulusBuffer.data())); // std::cout.write(stimulusBuffer.data(), strlen(stimulusBuffer.data()));
std::cout << "(" << signalBytesRead << " bytes of signal read), stimulus: " << &stimulusStream; std::cout << "(" << m_signalBytesRead << " bytes of signal read), stimulus: " << &m_stimulusStream;
// Tell ASIO to read again // Tell ASIO to read again
boost::asio::async_read_until(stimulusSocket, stimulusStream, "\n", boost::asio::async_read_until(m_stimulusSocket, m_stimulusStream, "\n",
boost::bind(&TCPWriterClient::stimulusHandler, this, boost::bind(&TCPWriterClient::stimulusHandler, this,
boost::asio::placeholders::error)); boost::asio::placeholders::error));
} }
...@@ -100,7 +124,7 @@ public: ...@@ -100,7 +124,7 @@ public:
std::cout << "Received signal header\n"; std::cout << "Received signal header\n";
const char *buf = signalBuffer.data(); const char *buf = m_signalHeaderBuffer.data();
// the print assumes the stream is little endian // the print assumes the stream is little endian
...@@ -110,11 +134,29 @@ public: ...@@ -110,11 +134,29 @@ public:
std::cout << " Channels: " << *(unsigned int *)&buf[12] << "\n"; std::cout << " Channels: " << *(unsigned int *)&buf[12] << "\n";
std::cout << " nSamples: " << *(unsigned int *)&buf[16] << "\n"; std::cout << " nSamples: " << *(unsigned int *)&buf[16] << "\n";
if(m_dataFile.is_open())
{
m_dataFile.write(buf, m_headerSize);
m_dataFile.flush();
}
std::cout << "Will now read signal in background.\n"; std::cout << "Will now read signal in background.\n";
std::cout << "Stimulations will be printed when received...\n"; if(m_stimulusSocket.is_open())
{
std::cout << "Stimulations will be printed when received...\n";
}
const int nChannels = *(unsigned int *)&buf[12];
const int nSamples = *(unsigned int *)&buf[16];
// Note that the buffer size should be the size of the chunk, or the read function may not launch the callback
// before the chunk has been filled. This can cause delays with sparse streams like classifier outputs.
m_bufferSize = nSamples*nChannels*sizeof(double);
m_signalBuffer.resize(m_bufferSize);
// Tell ASIO to read the actual signal // Tell ASIO to read the actual signal
boost::asio::async_read(signalSocket, boost::asio::buffer(signalBuffer.data(), bufferSize), boost::asio::async_read(m_signalSocket, boost::asio::buffer(m_signalBuffer.data(), m_bufferSize),
boost::asio::transfer_at_least(m_bufferSize),
boost::bind(&TCPWriterClient::signalHandler, this, boost::bind(&TCPWriterClient::signalHandler, this,
boost::asio::placeholders::error)); boost::asio::placeholders::error));
} }
...@@ -126,16 +168,23 @@ public: ...@@ -126,16 +168,23 @@ public:
throw boost::system::system_error(error); // Some other error. throw boost::system::system_error(error); // Some other error.
// signalBuffer will now contain bufferSize/sizeof(float64) amount of samples in float64s. Here we just discard the data. // signalBuffer will now contain bufferSize/sizeof(float64) amount of samples in float64s. Here we just discard the data.
const char *buf = signalBuffer.data(); const char *buf = m_signalBuffer.data();
const double* signalData = reinterpret_cast<const double*>(buf); const double* signalData = reinterpret_cast<const double*>(buf);
// Use this to fill your data matrix with the signal... // Use this to fill your data matrix with the signal...
(void)signalData; (void)signalData;
signalBytesRead += bufferSize; if(m_dataFile.is_open())
{
m_dataFile.write(buf, m_bufferSize);
m_dataFile.flush();
}
m_signalBytesRead += m_bufferSize;
// Tell ASIO to read more // Tell ASIO to read more
boost::asio::async_read(signalSocket, boost::asio::buffer(signalBuffer.data(), bufferSize), boost::asio::async_read(m_signalSocket, boost::asio::buffer(m_signalBuffer.data(), m_bufferSize),
boost::asio::transfer_at_least(m_bufferSize),
boost::bind(&TCPWriterClient::signalHandler, this, boost::bind(&TCPWriterClient::signalHandler, this,
boost::asio::placeholders::error)); boost::asio::placeholders::error));
} }
...@@ -148,27 +197,33 @@ int main(int argc, char** argv) ...@@ -148,27 +197,33 @@ int main(int argc, char** argv)
{ {
try try
{ {
if(argc>1 && ( (strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) || argc!=4 ) ) if( argc>1 && ( (strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) || (argc!=4 && argc!=5 ) ) )
{ {
std::cout << "Usage: " << argv[0] << " ip_address signal_port stimulus_port" << std::endl; std::cout << "Usage: " << argv[0] << " ip_address signal_port stimulus_port [signal_file]" << std::endl;
std::cout << "If no argument is given, the program tries to communicate on localhost using default port value." << std::endl; std::cout << "If no argument is given, the program tries to communicate on localhost using default port value." << std::endl;
std::cout << "Ports that are 0 will be skipped. Optional filename can be specified to write the signal to." << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
const char* l_sHostname = "localhost"; const char* l_sHostname = "localhost";
const char* l_sSignalPort = "5678"; const char* l_sSignalPort = "5678";
const char* l_sStimulusPort = "5679"; const char* l_sStimulusPort = "5679";
const char* l_sFilename = NULL;
if(argc == 4) if(argc >= 4)
{ {
l_sHostname = argv[1]; l_sSignalPort = argv[2]; l_sStimulusPort = argv[3]; l_sHostname = argv[1]; l_sSignalPort = argv[2]; l_sStimulusPort = argv[3];
} }
if(argc == 5)
{
l_sFilename = argv[4];
}
std::cout << "This example is intended to be used together with the tcp-writer.xml tutorial.\n\n"; std::cout << "This example is intended to be used together with the tcp-writer.xml tutorial.\n\n";
boost::asio::io_service ioService; boost::asio::io_service ioService;
TCPWriterClient client(ioService, l_sHostname, l_sSignalPort, l_sStimulusPort); TCPWriterClient client(ioService, l_sHostname, l_sSignalPort, l_sStimulusPort, l_sFilename);
ioService.run(); ioService.run();
} }
......
...@@ -17,10 +17,10 @@ Output: ...@@ -17,10 +17,10 @@ Output:
1b) If the output is chosen as hex string or descriptive string (these are valid for Stimulation input only), no header is sent. 1b) If the output is chosen as hex string or descriptive string (these are valid for Stimulation input only), no header is sent.
2) After the possible global header, the data itself is sent. The data is a stream of float64 for Signal and StreamedMatrix.