VAMatlabExecutable.cpp 122 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 *  --------------------------------------------------------------------------------------------
 *
 *    VVV        VVV A           Virtual Acoustics (VA) | http://www.virtualacoustics.org
 *     VVV      VVV AAA          Licensed under the Apache License, Version 2.0
 *      VVV    VVV   AAA
 *       VVV  VVV     AAA        Copyright 2015-2017
 *        VVVVVV       AAA       Institute of Technical Acoustics (ITA)
 *         VVVV         AAA      RWTH Aachen University
 *
 *  --------------------------------------------------------------------------------------------
 */

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
14 15
#include "VAMatlabFunctionMapping.h"
#include "VAMatlabHelpers.h"
16 17 18
#include "VAMatlabConnection.h"
#include "VAMatlabTracking.h"

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
19
 // Matlab includes
20 21 22 23
#include <mex.h>
#include <matrix.h>

// VA includes
24 25
#include <VA.h>
#include <VANet.h>
26 27 28 29 30 31 32

// STL includes
#include <algorithm>
#include <map>
#include <sstream>
#include <stdarg.h>

33 34 35 36
#ifdef WIN32
#include <windows.h>
#endif

37 38 39 40 41 42 43 44 45
// Maximum number of parallel connections
const int VAMATLAB_MAX_CONNECTIONS = 16;

// Connection handle datatype
typedef int32_t ConnectionHandle;
const mxClassID CONNECTIONHANDLE_CLASS_ID = mxINT32_CLASS;
const mxClassID ID_CLASS_ID = mxINT32_CLASS;


Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
46 47 48 49
bool g_bFirst = true;													// First call of Matlab mexFunction
std::vector<CVAMatlabConnection*> g_vpConnections( VAMATLAB_MAX_CONNECTIONS + 1, NULL );	// Hashtable handles -> connections (1st element always NULL)
ConnectionHandle g_iLastConnectionHandle = 0;							// Global connection ID counter
int g_iConnectionsEstablished = 0;									// Number of established connections
50
IVAInterface* g_pOwnCore = NULL;											// Own core instance (deploy mode 1)
51 52 53 54
CVAMatlabConnection g_oDummyConnection;										// Dummy 'connection' to own core (deploy mode 1)

#define VERBOSE_LEVEL_QUIET  0
#define VERBOSE_LEVEL_NORMAL 1
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
55
int g_iVerboseLevel = VERBOSE_LEVEL_NORMAL;							// Verbosity level
56 57 58 59 60 61 62 63


/* +------------------------------------------------------+
   |                                                      |
   |   Auxilary functions                                 |
   |                                                      |
   +------------------------------------------------------+ */

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
64
   // Verbose functions
65

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
66 67
void INFO( const char * format, ... )
{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
68 69
	if( g_iVerboseLevel == VERBOSE_LEVEL_QUIET )
		return; // Quiet?
70 71

	const int bufsize = 1024;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
72
	char buf[ bufsize ];
73 74

	va_list args;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
75 76 77
	va_start( args, format );
	vsprintf_s( buf, bufsize, format, args );
	va_end( args );
78

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
79
	mexPrintf( buf );
80 81 82
}

// Generate a new connection handle (ID)
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
83 84
ConnectionHandle GenerateConnectionHandle()
{
85 86 87
	// Scan for free entries starting from the last handle
	ConnectionHandle hHandle = -1;
	int i = g_iLastConnectionHandle;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
88 89
	do
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
90
		i = ( i + 1 ) % VAMATLAB_MAX_CONNECTIONS;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
91 92
		if( i == 0 )
			i++; // Skip placeholder
93

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
94 95
		if( g_vpConnections[ i ] == NULL )
		{
96 97 98
			g_iLastConnectionHandle = i;
			return i;
		}
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
99
	} while( hHandle == -1 );
100 101

	// Should not reach this line!
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
102
	VA_EXCEPT1( "An internal error occured - Please contact the developer" );
103 104 105
}

// Get connection handle from Matlab arguments and validate it
106 107
ConnectionHandle GetConnectionHandle( const mxArray *pArray, bool bAllowNullHandle = false )
{
108
	// Strict typing! Make sure that the parameter has a valid type (scalar + handle datatype)
109 110
	if( matlabIsScalar( pArray ) && ( mxGetClassID( pArray ) == CONNECTIONHANDLE_CLASS_ID ) )
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
111
		ConnectionHandle hHandle = *( ( ConnectionHandle* ) mxGetData( pArray ) );
112 113 114
		if( ( hHandle >= 0 ) && ( hHandle <= VAMATLAB_MAX_CONNECTIONS ) )
		{
			if( g_vpConnections[ hHandle ] || ( ( hHandle == 0 ) && bAllowNullHandle ) )
115 116 117 118
				return hHandle;
		}
	}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
119
	VA_EXCEPT1( "Invalid connection handle" );
120 121 122 123 124 125 126
}

// Checks if the correct excat number of arguments is provided
// and causes a Matlab error if not...
// USED FOR? Convenience baby! This saves some lines of code below ...
// NOTE: In this MEX we are always checking for the exact number of arguments
//       Optional values are predefined in the Matlab facade class
127 128 129 130 131 132
void vCheckInputArguments( int nrhs, int iRequiredNumArgs )
{
	if( nrhs != iRequiredNumArgs )
	{
		switch( iRequiredNumArgs )
		{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
133 134 135 136 137 138 139 140
		case 0: VA_EXCEPT1( "This VAMatlab function does not take any arguments" );
		case 1: VA_EXCEPT1( "This VAMatlab function takes exactly one argument" );
		case 2: VA_EXCEPT1( "This VAMatlab function takes exactly two arguments" );
		case 3: VA_EXCEPT1( "This VAMatlab function takes exactly three arguments" );
		case 4: VA_EXCEPT1( "This VAMatlab function takes exactly four arguments" );
		case 5: VA_EXCEPT1( "This VAMatlab function takes exactly five arguments" );
		case 6: VA_EXCEPT1( "This VAMatlab function takes exactly six arguments" );
			// Do we need more?
141
		default:
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
142 143 144 145 146
		{
			char buf[ 64 ];
			sprintf_s( buf, 64, "This VAMatlab function takes exactly %d arguments", iRequiredNumArgs );
			VA_EXCEPT1( buf );
		}
147 148 149 150 151 152 153
		}
	}
}

// Displays information in the executable in Matlab
void banner()
{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
154 155 156 157 158 159 160 161 162 163 164 165 166
	mexPrintf( "/*\n" );
	mexPrintf( " *  --------------------------------------------------------------------------------------------\n" );
	mexPrintf( " *\n" );
	mexPrintf( " *    VVV        VVV A           Virtual Acoustics (VA) | http://www.virtualacoustics.org\n" );
	mexPrintf( " *     VVV      VVV AAA          Licensed under the Apache License, Version 2.0\n" );
	mexPrintf( " *      VVV    VVV   AAA\n" );
	mexPrintf( " *       VVV  VVV     AAA        Copyright 2015-2017\n" );
	mexPrintf( " *        VVVVVV       AAA       Institute of Technical Acoustics (ITA)\n" );
	mexPrintf( " *         VVVV         AAA      RWTH Aachen University\n" );
	mexPrintf( " *\n" );
	mexPrintf( " *  --------------------------------------------------------------------------------------------\n" );
#ifdef VAMATLAB_INTEGRATED
	mexPrintf( " *                               VA Matlab with integrated core, version %s.%s\n", VAMATLAB_VERSION_MAJOR, VAMATLAB_VERSION_MINOR );
167
#else
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
168
	mexPrintf( " *    VA Matlab network client, version %s%s\n", VAMATLAB_VERSION_MAJOR, VAMATLAB_VERSION_MINOR );
169
#endif
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
170 171
	mexPrintf( " *  --------------------------------------------------------------------------------------------\n" );
	mexPrintf( " */\n" );
172 173 174
}

// Helper macro
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
175
#define REQUIRE_INPUT_ARGS( N ) vCheckInputArguments( nrhs, N )
176 177 178 179 180 181 182 183 184 185 186 187

/* +------------------------------------------------------+
   |                                                      |
   |   MEX Entry function                                 |
   |                                                      |
   +------------------------------------------------------+ */

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
	if( g_bFirst )
	{
		g_bFirst = false;
188
#ifdef VAMATLAB_SHOW_BANNER
189 190 191 192 193 194 195 196 197 198
		banner();
#endif
	}

	// At least one argument must be specified
	if( nrhs < 1 )
		mexErrMsgTxt( "Command argument expected" );

	try
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
199
		std::string sCommand = matlabGetString( prhs[ 0 ], "command" );
200 201 202 203 204 205 206 207 208

		// Convert command string to lowercase
		std::transform( sCommand.begin(), sCommand.end(), sCommand.begin(), toupper );
		FunctionMapIterator it = g_mFunctionMap.find( sCommand );
		if( it == g_mFunctionMap.end() )
			VA_EXCEPT1( "Invalid command argument '" + sCommand + "'" );

		// Call function (Skip first rhs 'command' argument for internal function calls)
		// Convert C++ exceptions into Matlab errors
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
209
		( *it->second.pAddr )( nlhs, plhs, nrhs - 1, &prhs[ 1 ] );
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
	}
	catch( CVAException& e )
	{
		mexErrMsgTxt( e.GetErrorMessage().c_str() );
	}
	catch( ... )
	{
		mexErrMsgTxt( "An internal error occured - Please contact the developer" );
	}
}


/* +------------------------------------------------------+
   |                                                      |
   |   Command functions                                  |
   |                                                      |
   +------------------------------------------------------+ */

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
228 229
   // Reflexion function. Returns cell-array of structs with information on the command functions.
   // Used for code generation of the Matlab MEX facade class [private]
230

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
231
REGISTER_PRIVATE_FUNCTION( enumerateFunctions );
232

233 234
void enumerateFunctions( int nlhs, mxArray *plhs[], int nrhs, const mxArray** )
{
235 236
	// Count public functions
	mwSize nPublicFuncs = 0;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
237 238
	for( FunctionMapIterator it = g_mFunctionMap.begin(); it != g_mFunctionMap.end(); ++it )
		if( it->second.bPublic ) nPublicFuncs++;
239 240

	const mwSize nFields = 5;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
241 242 243 244
	const char* ppszFieldNames[] = { "name", "inargs", "outargs", "desc", "doc" };

	mxArray* pStruct = mxCreateStructMatrix( 1, nPublicFuncs, nFields, ppszFieldNames );
	plhs[ 0 ] = pStruct;
245

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
246
	mwIndex i = 0;
247 248 249 250
	for( FunctionMapIterator it = g_mFunctionMap.begin(); it != g_mFunctionMap.end(); ++it )
	{
		if( !it->second.bPublic )
			continue;
251 252

		// Input arguments
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
253 254 255 256 257
		mxSetField( pStruct, i, ppszFieldNames[ 0 ], mxCreateString( it->second.sName.c_str() ) );
		mxSetField( pStruct, i, ppszFieldNames[ 1 ], CreateFunctionInputArgumentStruct( it->second.vInputArgs ) );
		mxSetField( pStruct, i, ppszFieldNames[ 2 ], CreateFunctionOutputArgumentStruct( it->second.vOutputArgs ) );
		mxSetField( pStruct, i, ppszFieldNames[ 3 ], mxCreateString( it->second.sDesc.c_str() ) );
		mxSetField( pStruct, i, ppszFieldNames[ 4 ], mxCreateString( it->second.sDoc.c_str() ) );
258 259 260 261 262 263 264 265 266 267 268

		i++;
	}
}

// ------------------------------------------------------------

REGISTER_PRIVATE_FUNCTION( getVersion );
void getVersion( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
	std::stringstream ss;
269 270 271 272 273 274
	ss << "VAMatlab " << VAMATLAB_VERSION_MAJOR << "." << VAMATLAB_VERSION_MINOR;
#ifdef DEBUG
	ss << " (debug)";
#else
	ss << " (release)";
#endif
275 276

	if( nlhs == 1 )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
277
		plhs[ 0 ] = mxCreateString( ss.str().c_str() );
278 279 280 281 282 283 284 285 286 287
	else
		mexPrintf( "%s", ss.str().c_str() );
}

// ------------------------------------------------------------

REGISTER_PRIVATE_FUNCTION( setVerboseMode );
void setVerboseMode( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
288 289 290 291 292 293
	REQUIRE_INPUT_ARGS( 1 );

	std::string sMode = matlabGetString( prhs[ 0 ], "mode" );
	std::transform( sMode.begin(), sMode.end(), sMode.begin(), toupper );

	if( sMode == "QUIET" ) {
294 295 296 297
		g_iVerboseLevel = VERBOSE_LEVEL_QUIET;
		return;
	}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
298
	if( sMode == "NORMAL" ) {
299 300 301 302
		g_iVerboseLevel = VERBOSE_LEVEL_NORMAL;
		return;
	}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
303
	VA_EXCEPT1( "Invalid verbose mode" );
304 305 306 307
}

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
308
REGISTER_PRIVATE_FUNCTION( get_connected );
309 310 311

#if VAMATLAB_INTEGRATED == 1

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
312
void get_connected( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
313

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
314
	REQUIRE_INPUT_ARGS( 1 );
315

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
316
	plhs[ 0 ] = mxCreateLogicalScalar( true );
317 318 319 320
};

#else // VAMATLAB_INTEGRATED

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
321
void get_connected( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
322

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
323
	REQUIRE_INPUT_ARGS( 1 );
324

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
325 326 327
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ], true );
	if( hHandle == 0 ) {
		plhs[ 0 ] = mxCreateLogicalScalar( false );
328 329 330
		return;
	}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
331
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
332
	bool bConnected = pConnection->pClient->IsConnected();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
333
	plhs[ 0 ] = mxCreateLogicalScalar( bConnected );
334 335 336 337 338 339
};

#endif // VAMATLAB_INTEGRATED

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
340
REGISTER_PRIVATE_FUNCTION( connect );
341 342 343

#if VAMATLAB_INTEGRATED == 1

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
344
void connect( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
345

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
346
	REQUIRE_INPUT_ARGS( 1 );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
347

348 349 350
	// Always connection ID 1
	ConnectionHandle hHandle = 1;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
351
	if( g_iConnectionsEstablished == 0 ) {
352 353 354
		try {
			std::string sPath = getDirectoryFromPath( VACore::GetCoreLibFilename() );
			std::string sConfigFile = combinePath( sPath, VA_DEFAULT_CONFIGFILE );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
355
			g_pOwnCore = VACore::CreateCoreInstance( sConfigFile );
356
			g_pOwnCore->Initialize();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
357 358
		}
		catch( CVAException& e ) {
359 360 361
			delete g_pOwnCore;
			g_pOwnCore = NULL;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
362 363 364 365 366
			char buf[ 4096 ];
			sprintf_s( buf, 4096, "Failed to initialize VACore. %s.", e.GetErrorMessage().c_str() );
			mexErrMsgTxt( buf );
		}
		catch( ... ) {
367 368 369
			delete g_pOwnCore;
			g_pOwnCore = NULL;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
370
			mexErrMsgTxt( "Failed to initialize VACore" );
371 372
		}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
373
		mexPrintf( "VACore initialized\n" );
374 375 376 377

		// First connection = Dummy connection to internal core
		g_oDummyConnection.pClient = NULL;
		g_oDummyConnection.pCoreInterface = g_pOwnCore;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
378
		g_vpConnections[ hHandle ] = &g_oDummyConnection;
379 380 381 382 383
	}

	++g_iConnectionsEstablished;

	// Return the handle
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
384
	plhs[ 0 ] = matlabCreateID( hHandle );
385 386 387 388
}

#else // VAMATLAB_INTEGRATED

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
389
void connect( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
390

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
391 392 393
	REQUIRE_INPUT_ARGS( 1 );

	std::string sRemoteAddress = matlabGetString( prhs[ 0 ], "address" );
394 395 396

	std::string sAddress;
	int iPort;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
397
	SplitServerString( sRemoteAddress, sAddress, iPort );
398 399 400

	if( g_iConnectionsEstablished == VAMATLAB_MAX_CONNECTIONS )
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
401
		VA_EXCEPT1( "Maximum number of connections reached. Close another opened connection first." );
402 403 404 405 406
		return;
	}

	CVAMatlabConnection* pConnection = new CVAMatlabConnection;
	// TODO: pConnection->pClient->AttachEventHandler(&g_oNetHandler);
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
407

408 409 410 411
	try
	{
		pConnection->pClient->Initialize( sAddress, iPort, IVANetClient::EXC_CLIENT_THROW, false );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
412
		if( !pConnection->pClient->IsConnected() )
413 414 415 416
		{
			// TODO: Delete object. Here were some error with double destruction. Exception in destr?
			std::stringstream ss;
			ss << "Connection to server \"" << sAddress << "\" failed";
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
417
			VA_EXCEPT1( ss.str() );
418 419 420 421 422 423
			return;
		}

		pConnection->pCoreInterface = pConnection->pClient->GetCoreInstance();
		pConnection->pVAMatlabTracker->pVACore = pConnection->pCoreInterface;

424
		CVAVersionInfo oRemoteCoreVersion;
425 426 427 428 429
		pConnection->pCoreInterface->GetVersionInfo( &oRemoteCoreVersion );

		CVANetVersionInfo oNetVersion;
		GetVANetVersionInfo( &oNetVersion );
	}
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
430
	catch( ... )
431 432 433 434 435 436
	{
		delete pConnection;
		throw;
	}

	ConnectionHandle hHandle = GenerateConnectionHandle();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
437
	g_vpConnections[ hHandle ] = pConnection;
438 439 440
	++g_iConnectionsEstablished;

	// Return the handle
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
441
	plhs[ 0 ] = matlabCreateID( hHandle );
442

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
443 444
	INFO( "Connection to VA server \"%s\" established (connection handle: %d)\n",
		pConnection->pClient->GetServerAddress().c_str(), hHandle );
445 446 447 448 449 450
}

#endif // VAMATLAB_INTEGRATED

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
451
REGISTER_PRIVATE_FUNCTION( disconnect );
452 453 454

#if VAMATLAB_INTEGRATED == 1

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
455
void disconnect( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
456

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
457
	REQUIRE_INPUT_ARGS( 1 );
458 459

	// Nothing to do ... Dummy function ...
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
460 461
	if( g_iConnectionsEstablished < 1 ) {
		VA_EXCEPT1( "No connections established" );
462 463 464 465
		return;
	}

	--g_iConnectionsEstablished;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
466
	g_vpConnections[ 1 ] = NULL;
467

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
468
	if( g_iConnectionsEstablished == 0 ) {
469 470 471 472 473
		// Aufrumen
		try {
			g_pOwnCore->Finalize();
			delete g_pOwnCore;
			g_pOwnCore = NULL;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
474 475
		}
		catch( CVAException& e ) {
476 477 478
			delete g_pOwnCore;
			g_pOwnCore = NULL;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
479 480 481
			char buf[ 4096 ];
			sprintf_s( buf, 4096, "Failed to finalize VACore. %s.", e.GetErrorMessage().c_str() );
			mexErrMsgTxt( buf );
482

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
483 484
		}
		catch( ... ) {
485 486 487
			delete g_pOwnCore;
			g_pOwnCore = NULL;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
488
			mexErrMsgTxt( "Failed to finalize VACore. An unknown error occured." );
489 490
		}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
491
		mexPrintf( "VACore finalized\n" );
492 493 494 495 496
	}
}

#else // VAMATLAB_INTEGRATED

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
497
void disconnect( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
498

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
499
	REQUIRE_INPUT_ARGS( 1 );
500

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
501 502
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ], true );
	if( hHandle == 0 ) return;
503

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
504
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
505

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
506
	std::string sAddr( pConnection->pClient->GetServerAddress() );
507

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
508
	g_vpConnections[ hHandle ] = NULL;
509 510 511
	--g_iConnectionsEstablished;
	delete pConnection;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
512 513
	INFO( "Disconnected from VA server \"%s\" (connection handle: %d)\n",
		sAddr.c_str(), hHandle );
514 515 516 517 518 519
}

#endif // VAMATLAB_INTEGRATED

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
520 521
REGISTER_PUBLIC_FUNCTION( get_server_address, "Returns for an opened connection the server it is connected to", "" );
DECLARE_FUNCTION_OUTARG( get_server_address, addr, "string", "Server address" );
522 523 524

#if VAMATLAB_INTEGRATED == 1

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
525
void get_server_address( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
526

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
527
	REQUIRE_INPUT_ARGS( 1 );
528 529

	// We not really have a connection. But definitely the core is on this machine... :-)
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
530
	prhs[ 0 ] = mxCreateString( "localhost" );
531 532 533 534 535
}


#else // VAMATLAB_INTEGRATED

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
536
void get_server_address( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
537

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
538
	REQUIRE_INPUT_ARGS( 1 );
539

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
540 541
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
542

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
543
	prhs[ 0 ] = mxCreateString( pConnection->pClient->GetServerAddress().c_str() );
544 545 546 547 548 549 550
}

#endif // VAMATLAB_INTEGRATED


// -------------------------- TRACKER ----------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
551 552 553 554
REGISTER_PRIVATE_FUNCTION( connect_tracker );
DECLARE_FUNCTION_OPTIONAL_INARG( connect_tracker, serverIP, "string", "Server IP", "''" );
DECLARE_FUNCTION_OPTIONAL_INARG( connect_tracker, localIP, "string", "Local IP", "''" );
void connect_tracker( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
555 556 557 558
{
	if( nrhs == 0 )
		VA_EXCEPT2( INVALID_PARAMETER, "Missing VA connection handle in ConnectTracker" );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
559 560
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
561
	CVAMatlabTracker* pTracker = pConnection->pVAMatlabTracker;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
562

563 564
	std::string sServerAdress = "127.0.0.1";
	if( nrhs > 1 )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
565 566
		sServerAdress = std::string( matlabGetString( prhs[ 1 ], "serverIP" ) );

567 568
	std::string sLocalAdress = "127.0.0.1";
	if( nrhs > 2 )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
569
		sLocalAdress = std::string( matlabGetString( prhs[ 2 ], "localIP" ) );
570 571

	if( pTracker->Initialize( sServerAdress, sLocalAdress ) == false )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
572
		VA_EXCEPT2( INVALID_PARAMETER, "Could not initialize connection to tracker with remote adress '" + sServerAdress
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
573
			+ "' and local adress '" + sLocalAdress + "'" );
574 575
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
576
REGISTER_PRIVATE_FUNCTION( disconnect_tracker );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
577
void disconnect_tracker( int , mxArray *[], int nrhs, const mxArray *prhs[] )
578 579 580
{
	REQUIRE_INPUT_ARGS( 1 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
581 582
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
583 584 585 586 587 588 589

	if( pConnection->pVAMatlabTracker->Uninitialize() == false )
		VA_EXCEPT2( INVALID_PARAMETER, "Could not disconnect from tracker" );

	pConnection->pVAMatlabTracker->Reset();
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
590 591 592
REGISTER_PRIVATE_FUNCTION( get_tracker_connected );
DECLARE_FUNCTION_OUTARG( get_tracker_connected, connected, "logical scalar", "True if a tracker connection is established" );
void get_tracker_connected( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
593 594
{
	REQUIRE_INPUT_ARGS( 1 );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
595 596 597

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
598
	CVAMatlabTracker* pTracker = pConnection->pVAMatlabTracker;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
599

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
600
	bool bIsConnected = pTracker->IsConnected();
601 602 603 604 605 606 607 608 609 610 611 612
	if( nlhs != 1 )
	{
		if( bIsConnected )
		{
			VA_EXCEPT2( INVALID_PARAMETER, "Can not return value, please provide exactly one left-hand side target value. But tracker is connected." );
		}
		else
		{
			VA_EXCEPT2( INVALID_PARAMETER, "Can not return value, please provide exactly one left-hand side target value. And tracker is not connected." );
		}
	}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
613
	plhs[ 0 ] = mxCreateLogicalScalar( bIsConnected );
614 615 616 617

	return;
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
618
// Tracked sound receiver
619

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
620
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_receiver );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
621
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_receiver, soundreceiverID, "scalar number", "Tracked sound receiver ID" );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
622
void set_tracked_sound_receiver( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
623 624 625
{
	REQUIRE_INPUT_ARGS( 2 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
626 627
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
628

629 630
	int isoundreceiverID = matlabGetIntegerScalar( prhs[ 1 ], "soundreceiverID" );
	pConnection->pVAMatlabTracker->iTrackedSoundReceiverID = isoundreceiverID;
631 632
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
633
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_receiver_rigid_body_index );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
634
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_receiver_rigid_body_index, index, "scalar number", "Tracked sound receiver rigid body index (default is 1)" );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
635
void set_tracked_sound_receiver_rigid_body_index( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
636 637 638 639 640 641 642 643
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

	int iTrackedRigidBodyIndex = matlabGetIntegerScalar( prhs[ 1 ], "index" );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
644
	pConnection->pVAMatlabTracker->iTrackedSoundReceiverRigidBodyIndex = iTrackedRigidBodyIndex;
645 646
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
647
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_receiver_rigid_body_translation );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
648
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_receiver_rigid_body_translation, offset, "real 1x3", "Tracked sound receiver rigid body position offset" );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
649
void set_tracked_sound_receiver_rigid_body_translation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
650 651 652 653 654 655
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

656 657
	VAVec3 v3Pos;
	matlabGetRealVector3( prhs[ 1 ], "offset", v3Pos );
658

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
659
	pConnection->pVAMatlabTracker->vTrackedSoundReceiverTranslation = VistaVector3D( float( v3Pos.x ), float( v3Pos.y ), float( v3Pos.z ) );
660 661
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
662
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_receiver_rigid_body_rotation );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
663
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_receiver_rigid_body_rotation, rotation, "real 1x4", "Tracked sound receiver rigid body rotation (quaternion values with w (real), i, j, k)" );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
664
void set_tracked_sound_receiver_rigid_body_rotation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
665 666 667 668 669 670
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

671 672
	VAQuat qOrient;
	matlabGetQuaternion( prhs[ 1 ], "rotation", qOrient );
673

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
674
	pConnection->pVAMatlabTracker->qTrackedSoundReceiverRotation = VistaQuaternion( float( qOrient.x ), float( qOrient.y ), float( qOrient.z ), float( qOrient.w ) );
675 676
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
677
// Tracked real-world sound receiver
678

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
679 680 681
REGISTER_PRIVATE_FUNCTION( set_tracked_real_world_sound_receiver );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_real_world_sound_receiver, realworldsoundreceiverID, "scalar number", "Tracked real-world sound receiver ID" );
void set_tracked_real_world_sound_receiver( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
682 683 684 685 686 687
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

688
	int iRealWorldsoundreceiverID = matlabGetIntegerScalar( prhs[ 1 ], "realworldsoundreceiverID" );
689

690
	pConnection->pVAMatlabTracker->iTrackedRealWorldSoundReceiverID = iRealWorldsoundreceiverID;
691 692
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
693 694 695
REGISTER_PRIVATE_FUNCTION( set_tracked_real_world_sound_receiver_rigid_body_index );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_real_world_sound_receiver_rigid_body_index, index, "scalar number", "Tracked real-world sound receiver rigid body index (default is 1)" );
void set_tracked_real_world_sound_receiver_rigid_body_index( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
696 697 698 699 700 701 702 703
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

	int iTrackedRigidBodyIndex = matlabGetIntegerScalar( prhs[ 1 ], "index" );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
704
	pConnection->pVAMatlabTracker->iTrackedRealWorldSoundReceiverRigidBodyIndex = iTrackedRigidBodyIndex;
705 706
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
707 708 709
REGISTER_PRIVATE_FUNCTION( set_tracked_real_world_sound_receiver_rigid_body_translation );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_real_world_sound_receiver_rigid_body_translation, offset, "real 1x3", "Tracked real-world sound receiver rigid body position offset" );
void set_tracked_real_world_sound_receiver_rigid_body_translation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
710 711 712 713 714 715
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

716 717
	VAVec3 v3Pos;
	matlabGetRealVector3( prhs[ 1 ], "offset", v3Pos );
718

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
719
	pConnection->pVAMatlabTracker->vTrackedRealWorldSoundReceiverTranslation = VistaVector3D( float( v3Pos.x ), float( v3Pos.y ), float( v3Pos.z ) );
720 721
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
722 723 724
REGISTER_PRIVATE_FUNCTION( set_tracked_real_world_sound_receiver_rigid_body_rotation );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_real_world_sound_receiver_rigid_body_rotation, rotation, "real 1x4", "Tracked real-world sound receiver rigid body rotation (quaternion values with w (real), i, j, k)" );
void set_tracked_real_world_sound_receiver_rigid_body_rotation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
725 726 727 728 729 730
{
	REQUIRE_INPUT_ARGS( 2 );

	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];

731 732
	VAQuat qOrient;
	matlabGetQuaternion( prhs[ 1 ], "rotation", qOrient );
733

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
734
	pConnection->pVAMatlabTracker->qTrackedRealWorldSoundReceiverRotation = VistaQuaternion( float( qOrient.x ), float( qOrient.y ), float( qOrient.z ), float( qOrient.w ) );
735 736 737 738
}

// Tracked source

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
739 740 741
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_source );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_source, sourceID, "scalar number", "Tracked source ID" );
void set_tracked_sound_source( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
742 743 744
{
	REQUIRE_INPUT_ARGS( 2 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
745 746
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
747

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
748
	int iSourceID = matlabGetIntegerScalar( prhs[ 1 ], "sourceID" );
749

750 751 752
	pConnection->pVAMatlabTracker->iTrackedSourceID = iSourceID;
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
753 754 755
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_source_rigid_body_index );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_source_rigid_body_index, index, "scalar number", "Tracked source rigid body index (default is 1)" );
void set_tracked_sound_source_rigid_body_index( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
756 757 758
{
	REQUIRE_INPUT_ARGS( 2 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
759 760
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
761

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
762
	int iTrackedRigidBodyIndex = matlabGetIntegerScalar( prhs[ 1 ], "index" );
763

764
	pConnection->pVAMatlabTracker->iTrackedSourceRigidBodyIndex = iTrackedRigidBodyIndex;
765 766
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
767 768 769
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_source_rigid_body_translation );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_source_rigid_body_translation, offset, "real 1x3", "Tracked source rigid body position offset" );
void set_tracked_sound_source_rigid_body_translation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
770 771 772
{
	REQUIRE_INPUT_ARGS( 2 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
773 774
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
775

776 777
	VAVec3 v3Pos;
	matlabGetRealVector3( prhs[ 1 ], "offset", v3Pos );
778

779
	pConnection->pVAMatlabTracker->vTrackedSourceTranslation = VistaVector3D( v3Pos.comp );
780 781
}

782 783 784
REGISTER_PRIVATE_FUNCTION( set_tracked_sound_source_rigid_body_rotation );
DECLARE_FUNCTION_REQUIRED_INARG( set_tracked_sound_source_rigid_body_rotation, rotation, "real 1x4", "Tracked sound source rigid body rotation (quaternion values with w (real), i, j, k)" );
void set_tracked_sound_source_rigid_body_rotation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
785 786 787
{
	REQUIRE_INPUT_ARGS( 2 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
788 789
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
790

791 792
	VAQuat qOrient;
	matlabGetQuaternion( prhs[ 1 ], "rotation", qOrient );
793

794
	pConnection->pVAMatlabTracker->qTrackedSourceRotation = VistaQuaternion( qOrient.comp );
795 796
}

797

798 799 800 801 802 803
/* +----------------------------------------------------------+ *
 * |                                                          | *
 * |   Base functions                                         | *
 * |                                                          | *
 * +----------------------------------------------------------+ */

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
804
REGISTER_PRIVATE_FUNCTION( get_server_state );
805

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
806
void get_server_state( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
807

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
808
	REQUIRE_INPUT_ARGS( 1 );
809

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
810 811
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
812

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
813
	plhs[ 0 ] = matlabCreateID( pConnection->pCoreInterface->GetState() );
814 815 816 817
}

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
818
REGISTER_PUBLIC_FUNCTION( reset, "Resets the VA server", "" );
819 820 821

#if VAMATLAB_INTEGRATED == 1

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
822
void reset( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
823

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
824
	REQUIRE_INPUT_ARGS( 1 );
825

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
826
	INFO( "Resetting VA core\n" );
827 828 829 830 831 832

	g_pOwnCore->Reset();
}

#else // VAMATLAB_INTEGRATED

833 834
void reset( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
835
	REQUIRE_INPUT_ARGS( 1 );
836

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
837 838
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
839

840
	INFO( "Resetting VA server \"%s\" (connection handle: %d)\n", pConnection->pClient->GetServerAddress().c_str(), hHandle );
841 842 843 844 845 846 847 848 849 850 851 852

	pConnection->pCoreInterface->Reset();
}

#endif // VAMATLAB_INTEGRATED

/* +----------------------------------------------------------+ *
 * |                                                          | *
 * |   Module interface                                       | *
 * |                                                          | *
 * +----------------------------------------------------------+ */

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
853 854 855
REGISTER_PUBLIC_FUNCTION( get_modules, "Enumerates internal modules of the VA server", "" );
DECLARE_FUNCTION_OUTARG( get_modules, modules, "cell-array of struct-1x1", "Module informations (names, descriptions, etc.)" );
void get_modules( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
856 857 858 859
{

	REQUIRE_INPUT_ARGS( 1 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
860 861
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
862 863

	std::vector< CVAModuleInfo > v;
864
	pConnection->pCoreInterface->GetModules( v );
865

866
	const size_t nDims = int( v.size() );
867 868
	const int nFields = 2;
	const char* ppszFieldNames[] = { "name", "desc" };
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
869
	plhs[ 0 ] = mxCreateStructArray( 1, &nDims, nFields, ppszFieldNames );
870

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
871
	for( size_t i = 0; i < nDims; i++ )
872
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
873 874
		mxSetField( plhs[ 0 ], i, ppszFieldNames[ 0 ], mxCreateString( v[ i ].sName.c_str() ) );
		mxSetField( plhs[ 0 ], i, ppszFieldNames[ 1 ], mxCreateString( v[ i ].sDesc.c_str() ) );
875 876 877 878 879 880 881
	}

	return;
}

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
882 883 884 885 886
REGISTER_PUBLIC_FUNCTION( call_module, "Calls an internal module of the VA server", "" );
DECLARE_FUNCTION_REQUIRED_INARG( call_module, module, "string", "Module name" );
DECLARE_FUNCTION_REQUIRED_INARG( call_module, mstruct, "struct", "Matlab structure with key-value content" );
DECLARE_FUNCTION_OUTARG( call_module, ret, "struct-1x1", "Struct containing the return values" );
void call_module( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
887 888 889 890
{
	if( nrhs != 3 )
		VA_EXCEPT2( INVALID_PARAMETER, "This function takes three arguments (connection, module, params)" );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
891 892
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
893

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
894 895
	std::string sModuleName = matlabGetString( prhs[ 1 ], "module" );
	CVAStruct oArgs = matlabGetStruct( prhs[ 2 ], "mstruct" );
896 897 898

	CVAStruct oReturn;

899
	oReturn = pConnection->pCoreInterface->CallModule( sModuleName, oArgs );
900 901 902

	if( nlhs == 0 )
		return;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
903

904 905 906
	if( nlhs == 1 )
	{
		mxArray* pReturnArray = matlabCreateStruct( oReturn );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
907
		plhs[ 0 ] = pReturnArray;
908 909 910 911 912 913 914 915 916
	}
	else
	{
		VA_EXCEPT2( INVALID_PARAMETER, "Too many left-hand-side return arguments given, this function returns a single argument (as struct) or nothing" );
	}

	return;
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
917 918 919 920
REGISTER_PUBLIC_FUNCTION( add_search_path, "adds a search path at core side", "" );
DECLARE_FUNCTION_REQUIRED_INARG( add_search_path, path, "string", "Relative or absolute path" );
DECLARE_FUNCTION_OUTARG( add_search_path, valid, "logical scalar", "True, if path at core side valid" );
void add_search_path( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
921 922 923
{
	REQUIRE_INPUT_ARGS( 2 );

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
924 925
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
926

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
927
	std::string sPath = matlabGetString( prhs[ 1 ], "path" );
928
	bool bValid = pConnection->pCoreInterface->AddSearchPath( sPath );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
929
	plhs[ 0 ] = mxCreateLogicalScalar( bValid );
930 931 932 933 934 935 936 937 938 939

	return;
}

/* +----------------------------------------------------------+ *
 * |                                                          | *
 * |   Directivities                                          | *
 * |                                                          | *
 * +----------------------------------------------------------+ */

940 941 942 943
REGISTER_PUBLIC_FUNCTION( create_directivity, "Loads a directivity from a file", "" );
DECLARE_FUNCTION_REQUIRED_INARG( create_directivity, filename, "string", "Filename" );
DECLARE_FUNCTION_OPTIONAL_INARG( create_directivity, name, "string", "Displayed name", "''" );
DECLARE_FUNCTION_OUTARG( create_directivity, directivityID, "integer-1x1", "Directivity ID" );
944

945
void create_directivity( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
946

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
947
	REQUIRE_INPUT_ARGS( 3 );
948

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
949 950
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
951

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
952 953
	std::string sFilename = matlabGetString( prhs[ 1 ], "filename" );
	std::string sName = matlabGetString( prhs[ 2 ], "Name" );
954

955
	int iDirectivityID = pConnection->pCoreInterface->CreateDirectivityFromFile( sFilename, sName );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
956
	plhs[ 0 ] = matlabCreateID( iDirectivityID );
957

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
958
	INFO( "Loaded directivity \"%s\" successfully loaded (id: %d)\n", sFilename.c_str(), hHandle );
959 960 961 962
}

// ------------------------------------------------------------

963 964 965
REGISTER_PUBLIC_FUNCTION( delete_directivity, "Frees a directivity and releases its memory", "This is only possible if the directivity is not in use. Otherwise the method will do nothing." );
DECLARE_FUNCTION_REQUIRED_INARG( delete_directivity, directivityID, "integer-1x1", "Directivity ID" );
DECLARE_FUNCTION_OUTARG( delete_directivity, result, "logical-1x1", "Directivity freed?" );
966

967
void delete_directivity( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
968

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
969
	REQUIRE_INPUT_ARGS( 2 );
970

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
971 972
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
973

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
974
	int iDirectivityID = matlabGetIntegerScalar( prhs[ 1 ], "directivityID" );
975

976
	bool bResult = pConnection->pCoreInterface->DeleteDirectivity( iDirectivityID );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
977
	plhs[ 0 ] = mxCreateLogicalScalar( bResult );
978 979 980 981
}

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
982 983 984
REGISTER_PUBLIC_FUNCTION( get_directivity_info, "Returns information on a loaded directivity", "" );
DECLARE_FUNCTION_REQUIRED_INARG( get_directivity_info, directivityID, "integer-1x1", "Directivity ID" );
DECLARE_FUNCTION_OUTARG( get_directivity_info, info, "struct-1x1", "Information struct (name, filename, resolution, etc.)" );
985

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
986
void get_directivity_info( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
987

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
988
	REQUIRE_INPUT_ARGS( 2 );
989

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
990 991
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
992

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
993 994 995
	int iDirectivityID = matlabGetIntegerScalar( prhs[ 1 ], "directivityID" );
	CVADirectivityInfo di = pConnection->pCoreInterface->GetDirectivityInfo( iDirectivityID );
	plhs[ 0 ] = matlabCreateDirectivityInfo( di );
996 997 998 999
}

// ------------------------------------------------------------

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1000 1001
REGISTER_PUBLIC_FUNCTION( get_directivity_infos, "Returns information on all loaded directivities", "" );
DECLARE_FUNCTION_OUTARG( get_directivity_infos, info, "cell-array of struct-1x1", "Information structs (name, filename, resolution, etc.)" );
1002

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1003
void get_directivity_infos( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
1004

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1005
	REQUIRE_INPUT_ARGS( 1 );
1006

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1007 1008
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConnection = g_vpConnections[ hHandle ];
1009 1010

	std::vector<CVADirectivityInfo> v;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1011
	pConnection->pCoreInterface->GetDirectivityInfos( v );
1012

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1013 1014 1015 1016
	const mwSize dims[ 2 ] = { 1, v.size() };
	mxArray* pCell = mxCreateCellArray( 2, dims );
	for( size_t i = 0; i < v.size(); i++ )
		mxSetCell( pCell, i, matlabCreateDirectivityInfo( v[ i ] ) );
1017

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1018
	plhs[ 0 ] = pCell;
1019 1020 1021 1022
}

/* +----------------------------------------------------------+ *
 * |                                                          | *
1023
 * |   Signal sources                                         | *
1024 1025 1026
 * |                                                          | *
 * +----------------------------------------------------------+ */

1027 1028 1029 1030
REGISTER_PUBLIC_FUNCTION( create_signal_source_buffer_from_file, "Creates a signal source which plays an audiofile", "Note: The audiofile must be mono and its sampling rate must match that of the server." );
DECLARE_FUNCTION_REQUIRED_INARG( create_signal_source_buffer_from_file, filename, "string", "Filename" );
DECLARE_FUNCTION_OPTIONAL_INARG( create_signal_source_buffer_from_file, name, "string", "Displayed name", "''" );
DECLARE_FUNCTION_OUTARG( create_signal_source_buffer_from_file, signalSourceID, "string", "Signal source ID" );
1031

1032 1033
void create_signal_source_buffer_from_file( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1034
	REQUIRE_INPUT_ARGS( 3 );
1035

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
1036 1037
	ConnectionHandle hHandle = GetConnectionHandle( prhs[ 0 ] );
	CVAMatlabConnection* pConn