init
This commit is contained in:
Executable
+34
@@ -0,0 +1,34 @@
|
||||
PROJECT(openvibe-examples-openvibe-to-tcpip)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION ${OV_GLOBAL_VERSION_STRING})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp src/*.inl include/*.h)
|
||||
INCLUDE_DIRECTORIES(include)
|
||||
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
|
||||
|
||||
INCLUDE("FindThirdPartyBoost")
|
||||
INCLUDE("FindThirdPartyBoost_System")
|
||||
INCLUDE("FindThirdPartyPThread") # for ubuntu
|
||||
|
||||
# ---------------------------------
|
||||
IF(WIN32)
|
||||
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) # for boost::asio
|
||||
ENDIF(WIN32)
|
||||
|
||||
# ----------------------
|
||||
# Generate launch script
|
||||
# ----------------------
|
||||
OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX "${PROJECT_NAME}" EXECUTABLE_NAME "${PROJECT_NAME}")
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials)
|
||||
+449
@@ -0,0 +1,449 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>2</FormatVersion>
|
||||
<Creator>OpenViBE Designer</Creator>
|
||||
<CreatorVersion>2.1.0</CreatorVersion>
|
||||
<Settings></Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x00000d28, 0x00002d38)</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>Output format</Name>
|
||||
<DefaultValue>Raw</DefaultValue>
|
||||
<Value>String</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>400</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x7a1f4e3a, 0x74c05f92)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</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>
|
||||
<Identifier>(0x00000d28, 0x00002d39)</Identifier>
|
||||
<Name>Signal to TCP</Name>
|
||||
<AlgorithmClassIdentifier>(0x02f24947, 0x17fa0477)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Input 1</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Port</Name>
|
||||
<DefaultValue>5678</DefaultValue>
|
||||
<Value>5678</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x77d3e238, 0xb954ec48)</TypeIdentifier>
|
||||
<Name>Output format</Name>
|
||||
<DefaultValue>Raw</DefaultValue>
|
||||
<Value>Raw</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>400</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>208</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x7a1f4e3a, 0x74c05f92)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</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>
|
||||
<Identifier>(0x00002055, 0x00006c8d)</Identifier>
|
||||
<Name>Sinus oscillator</Name>
|
||||
<AlgorithmClassIdentifier>(0x7e33bdb8, 0x68194a4a)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Generated signal</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Channel count</Name>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
<Value>5</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Sampling frequency</Name>
|
||||
<DefaultValue>512</DefaultValue>
|
||||
<Value>256</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Generated epoch sample count</Name>
|
||||
<DefaultValue>32</DefaultValue>
|
||||
<Value>32</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>160</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>224</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x0b214ed8, 0x1f9ad83a)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
|
||||
<Value>(0x00000000, 0x015d7484)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>3</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x0000360b, 0x0000614e)</Identifier>
|
||||
<Name>Signal display</Name>
|
||||
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Data</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Stimulations</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
|
||||
<Name>Channel Units</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
|
||||
<Name>Display Mode</Name>
|
||||
<DefaultValue>Scan</DefaultValue>
|
||||
<Value>Scan</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
|
||||
<Name>Auto vertical scale</Name>
|
||||
<DefaultValue>Per channel</DefaultValue>
|
||||
<Value>Per channel</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Scale refresh interval (secs)</Name>
|
||||
<DefaultValue>5</DefaultValue>
|
||||
<Value>5</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Vertical Scale</Name>
|
||||
<DefaultValue>100</DefaultValue>
|
||||
<Value>100</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Vertical Offset</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Value>0</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Time Scale</Name>
|
||||
<DefaultValue>10</DefaultValue>
|
||||
<Value>10</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Horizontal ruler</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Vertical ruler</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Multiview</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>304</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>352</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x92c056a7, 0x2dc71aff)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
|
||||
<Value>(0x00000000, 0x01e683c6)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
|
||||
<Value>false</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>9</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>3</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x000047dd, 0x00002575)</Identifier>
|
||||
<Name>Keyboard stimulator</Name>
|
||||
<AlgorithmClassIdentifier>(0x00d317b9, 0x6324c3ff)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Outgoing Stimulations</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Filename</Name>
|
||||
<DefaultValue>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</DefaultValue>
|
||||
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>160</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>448</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
|
||||
<Value>(0x00000000, 0x01b4ded6)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x000027e0, 0x00000a8f)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x000047dd, 0x00002575)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x0000360b, 0x0000614e)</BoxIdentifier>
|
||||
<BoxInputIndex>1</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00002f08, 0x0000570a)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x000047dd, 0x00002575)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x00000d28, 0x00002d38)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x000051f8, 0x00001525)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00002055, 0x00006c8d)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x00000d28, 0x00002d39)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x000065a0, 0x0000405a)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00002055, 0x00006c8d)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x0000360b, 0x0000614e)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments>
|
||||
<Comment>
|
||||
<Identifier>(0x000008fe, 0x00004de5)</Identifier>
|
||||
<Text>This scenario shows how to send data out from Designer to a TCP/IP client
|
||||
|
||||
Its used together with <b>openvibe-examples-openvibe-to-tcpip</b> application.
|
||||
|
||||
First, start the scenario, and then the application. Then, press a key 'a'
|
||||
in the Keyboard Stimulator window to see it printed on the side of
|
||||
the client along with the number of signal bytes received so far.</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>336.000000</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>65.000000</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
</Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0x0000360b, 0x0000614e)","childCount":0,"identifier":"(0x000064a1, 0x00002649)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0x000047dd, 0x00002575)","childCount":0,"identifier":"(0x000067f8, 0x000057b7)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x0000736a, 0x00003296)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":475},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x0000673a, 0x00000342)","index":0,"name":"Default tab","parentIdentifier":"(0x0000736a, 0x00003296)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00001000, 0x00005b38)","index":0,"name":"Empty","parentIdentifier":"(0x0000673a, 0x00000342)","type":0}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
|
||||
<Value>Jussi T. Lindgren</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
|
||||
<Value>1.0</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
|
||||
<Value>OpenViBE to TCP/IP tutorial</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
|
||||
<Value>box-tutorials</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
|
||||
<Value>Inria</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</OpenViBE-Scenario>
|
||||
Executable
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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
|
||||
* are printed first. If a stimulus is received, the code will print out the stimulus
|
||||
* 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.
|
||||
* 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'
|
||||
*
|
||||
* \author Jussi T. Lindgren (Inria)
|
||||
* \date 20 May 11 12:55:22 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TARGET_HAS_Boost
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
/*
|
||||
* \class TCPWriterClient
|
||||
* \brief Basic illustratation of how to read from TCPWriter using boost::asio
|
||||
*/
|
||||
class TCPWriterClient
|
||||
{
|
||||
protected:
|
||||
tcp::socket m_stimulusSocket;
|
||||
tcp::socket m_signalSocket;
|
||||
|
||||
static const int HEADER_SIZE = 32; // signal header size
|
||||
int m_bufferSize = 0; // signal buffer size
|
||||
|
||||
std::array<char, HEADER_SIZE> m_signalHeaderBuffer;
|
||||
std::vector<char> m_signalBuffer;
|
||||
|
||||
uint64_t m_signalBytesRead = 0; // how many bytes of signal read so far
|
||||
|
||||
boost::asio::streambuf m_stimulusStream;
|
||||
|
||||
std::ofstream m_dataFile;
|
||||
|
||||
public:
|
||||
~TCPWriterClient() { if (m_dataFile.is_open()) { m_dataFile.close(); } }
|
||||
|
||||
TCPWriterClient(boost::asio::io_service& ioService, const char* address, const char* signalPort, const char* stimulusPort, const char* dataFilename)
|
||||
: m_stimulusSocket(ioService), m_signalSocket(ioService)
|
||||
{
|
||||
boost::system::error_code error;
|
||||
tcp::resolver resolver(ioService);
|
||||
|
||||
if (dataFilename != nullptr) { m_dataFile.open(dataFilename, std::ios::binary | std::ios::trunc | std::ios::out); }
|
||||
|
||||
if ((stimulusPort != nullptr) && strcmp(stimulusPort, "0") != 0)
|
||||
{
|
||||
// Stimulus port
|
||||
std::cout << "Connecting to stimulus port [" << address << " : " << stimulusPort << "]\n";
|
||||
const tcp::resolver::query query = tcp::resolver::query(tcp::v4(), address, stimulusPort);
|
||||
m_stimulusSocket.connect(*resolver.resolve(query), error);
|
||||
|
||||
// Tell ASIO to read a stimulus
|
||||
async_read_until(m_stimulusSocket, m_stimulusStream, "\n", boost::bind(&TCPWriterClient::stimulusHandler, this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
if ((signalPort != nullptr) && strcmp(signalPort, "0") != 0)
|
||||
{
|
||||
// Signal port
|
||||
std::cout << "Connecting to signal port [" << address << " : " << signalPort << "]\n";
|
||||
const tcp::resolver::query query = tcp::resolver::query(tcp::v4(), address, signalPort);
|
||||
m_signalSocket.connect(*resolver.resolve(query), error);
|
||||
|
||||
const tcp::no_delay noDelay(true);
|
||||
m_signalSocket.set_option(noDelay);
|
||||
|
||||
// Tell ASIO to read the signal header
|
||||
async_read(m_signalSocket, boost::asio::buffer(m_signalHeaderBuffer.data(), HEADER_SIZE), boost::asio::transfer_at_least(HEADER_SIZE),
|
||||
boost::bind(&TCPWriterClient::signalHeaderHandler, this, boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stimulusHandler(const boost::system::error_code& error)
|
||||
{
|
||||
if (error == boost::asio::error::eof) { return; } // Connection closed cleanly by peer.
|
||||
if (error.value() != 0) { throw boost::system::system_error(error); } // Some other error.
|
||||
|
||||
// std::cout.write(stimulusBuffer.data(), strlen(stimulusBuffer.data()));
|
||||
std::cout << "(" << m_signalBytesRead << " bytes of signal read), stimulus: " << &m_stimulusStream;
|
||||
|
||||
// Tell ASIO to read again
|
||||
async_read_until(m_stimulusSocket, m_stimulusStream, "\n", boost::bind(&TCPWriterClient::stimulusHandler, this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void signalHeaderHandler(const boost::system::error_code& error)
|
||||
{
|
||||
if (error == boost::asio::error::eof) { return; } // Connection closed cleanly by peer.
|
||||
if (error.value() != 0) { throw boost::system::system_error(error); } // Some other error.
|
||||
|
||||
std::cout << "Received signal header\n";
|
||||
|
||||
const char* buf = m_signalHeaderBuffer.data();
|
||||
|
||||
// the print assumes the stream is little endian
|
||||
|
||||
std::cout << " Version: " << ntohl(*(uint32_t*)&buf[0]) << "\n";
|
||||
std::cout << " Endianness: " << ntohl(*(uint32_t*)&buf[4]) << "\n";
|
||||
std::cout << " Hz: " << *(uint32_t*)&buf[8] << "\n";
|
||||
std::cout << " Channels: " << *(uint32_t*)&buf[12] << "\n";
|
||||
std::cout << " nSamples: " << *(uint32_t*)&buf[16] << "\n";
|
||||
|
||||
if (m_dataFile.is_open())
|
||||
{
|
||||
m_dataFile.write(buf, HEADER_SIZE);
|
||||
m_dataFile.flush();
|
||||
}
|
||||
|
||||
std::cout << "Will now read signal in background.\n";
|
||||
if (m_stimulusSocket.is_open()) { std::cout << "Stimulations will be printed when received...\n"; }
|
||||
|
||||
const size_t nChannels = size_t(*(uint32_t*)&buf[12]);
|
||||
const size_t nSamples = size_t(*(uint32_t*)&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 = int(nSamples * nChannels * sizeof(double));
|
||||
m_signalBuffer.resize(m_bufferSize);
|
||||
|
||||
// Tell ASIO to read the actual signal
|
||||
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::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void signalHandler(const boost::system::error_code& error)
|
||||
{
|
||||
if (error == boost::asio::error::eof) { return; } // Connection closed cleanly by peer.
|
||||
if (error.value() != 0) { throw boost::system::system_error(error); } // Some other error.
|
||||
|
||||
// signalBuffer will now contain bufferSize/sizeof(double) amount of samples in doubles. Here we just discard the data.
|
||||
const char* buf = m_signalBuffer.data();
|
||||
//const double* signalData = reinterpret_cast<const double*>(buf); Use this to fill your data matrix with the signal...
|
||||
|
||||
if (m_dataFile.is_open())
|
||||
{
|
||||
m_dataFile.write(buf, m_bufferSize);
|
||||
m_dataFile.flush();
|
||||
}
|
||||
|
||||
m_signalBytesRead += m_bufferSize;
|
||||
|
||||
// Tell ASIO to read more
|
||||
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::asio::placeholders::error));
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
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 [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 << "Ports that are 0 will be skipped. Optional filename can be specified to write the signal to." << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
const char* hostname = "localhost";
|
||||
const char* signalPort = "5678";
|
||||
const char* stimulusPort = "5679";
|
||||
const char* filename = nullptr;
|
||||
|
||||
if (argc >= 4)
|
||||
{
|
||||
hostname = argv[1];
|
||||
signalPort = argv[2];
|
||||
stimulusPort = argv[3];
|
||||
}
|
||||
if (argc == 5) { filename = argv[4]; }
|
||||
|
||||
std::cout << "This example is intended to be used together with the tcp-writer.xml tutorial.\n\n";
|
||||
boost::asio::io_service ioService;
|
||||
TCPWriterClient client(ioService, hostname, signalPort, stimulusPort, filename);
|
||||
ioService.run();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user