Skip to content
Snippets Groups Projects
Select Git revision
  • 1012700bdf28339ebf98a23c18a32b1d02d432aa
  • main default protected
  • dev protected
  • Issue/3090-tosProblems
  • Issue/3178-iconColorBug
  • Issue/3176-addNewNFDI4INGLogo
  • Issue/3141-rdsNoLonga
  • Issue/3180-fixMetadataNotLoading
  • Issue/3177-resourceTypeDescriptionTexts
  • Issue/3160-deactivateDownloadForFolders
  • Issue/3111-fixLoadingGitLabResource
  • Issue/3133-subProjectsChanges
  • Issue/3139-dsnrw
  • Issue/3167-changeTextAndAddLink
  • Issue/3070-newIconsForResourceTypes
  • Issue/3145-redesignLoginPage
  • Issue/3093-moreInformationInTheDeletionEmails
  • Issue/3040-closeTokenWindowWithXButton
  • Issue/3152-fixResourceStore
  • Issue/xxxx-DuckDBTest
  • Issue/3152-fixUpdateRequestPayload
  • v3.19.1
  • v3.19.0
  • v3.18.0
  • v3.17.2
  • v3.17.1
  • v3.17.0
  • v3.16.1
  • v3.16.0
  • v3.15.6
  • v3.15.5
  • v3.15.4
  • v3.15.3
  • v3.15.2
  • v3.15.1
  • v3.15.0
  • v3.14.0
  • v3.13.1
  • v3.13.0
  • v3.12.0
  • v3.11.0
41 results

ApplicationProfile.vue

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    VAMatlabExecutable.cpp 136.93 KiB
    /*
     *
     *    VVV        VVV A
     *     VVV      VVV AAA        Virtual Acoustics
     *      VVV    VVV   AAA       Real-time auralisation for virtual reality    
     *       VVV  VVV     AAA
     *        VVVVVV       AAA     (c) Copyright Institut fr Technische Akustik (ITA)
     *         VVVV         AAA        RWTH Aachen (http://www.akustik.rwth-aachen.de)
     *
     *  ---------------------------------------------------------------------------------
     *
     *    File:				VAMatlabExecutable.cpp 
     *
     *    Purpose:			MEX Executable for remote operation of VA using Matlab
     *
     *    Authors:			Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
     *						Christian Haar (Christian.Haar@akustik.rwth-aachen.de)
     *
     *  ---------------------------------------------------------------------------------
     */
      
    // $Id: VAMatlabExecutable.cpp 2422 2012-04-25 11:32:10Z fwefers $
    
    #include "FunctionMappings.h"
    #include "MatlabHelpers.h"
    #include "VAMatlabConnection.h"
    #include "VAMatlabTracking.h"
    
    // Matlab includes
    #include <mex.h>
    #include <matrix.h>
    
    // VA includes
    #include <VABaseDefinitions.h>
    #include <VACore.h>
    #include <VACoreVersion.h>
    //#include <VACoreFactory.h>
    #include <VAException.h>
    #include <VANetClient.h>
    #include <VANetUtils.h>
    #include <VANetVersion.h>
    #include <VAStruct.h>
    
    // STL includes
    #include <algorithm>
    #include <map>
    #include <sstream>
    #include <stdarg.h>
    
    #ifdef WIN32
    #include <windows.h>
    #undef PlaySound
    #endif
    
    // 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;
    
    
    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
    IVACore* g_pOwnCore=NULL;											// Own core instance (deploy mode 1)
    CVAMatlabConnection g_oDummyConnection;										// Dummy 'connection' to own core (deploy mode 1)
    
    #define VERBOSE_LEVEL_QUIET  0
    #define VERBOSE_LEVEL_NORMAL 1
    int g_iVerboseLevel=VERBOSE_LEVEL_NORMAL;							// Verbosity level
    
    
    /* +------------------------------------------------------+
       |                                                      |
       |   Auxilary functions                                 |
       |                                                      |
       +------------------------------------------------------+ */
    
    // Verbose functions
    
    void INFO(const char * format, ... ) {
    	if (g_iVerboseLevel == VERBOSE_LEVEL_QUIET) return; // Quiet?
    
    	const int bufsize = 1024;
    	char buf[bufsize];
    
    	va_list args;
    	va_start(args, format);
    	vsprintf_s(buf, bufsize, format, args);
    	va_end(args);
    
    	mexPrintf(buf);
    }
    
    // Generate a new connection handle (ID)
    ConnectionHandle GenerateConnectionHandle() {
    	// Scan for free entries starting from the last handle
    	ConnectionHandle hHandle = -1;
    	int i = g_iLastConnectionHandle;
    	do {
    		i = (i+1) % VAMATLAB_MAX_CONNECTIONS;
    		if (i==0) i++; // Skip placeholder
    
    		if (g_vpConnections[i] == NULL) {
    			g_iLastConnectionHandle = i;
    			return i;
    		}
    	} while (hHandle == -1);
    
    	// Should not reach this line!
    	VA_EXCEPT1("An internal error occured - Please contact the developer");
    	return -1;
    }
    
    // Get connection handle from Matlab arguments and validate it
    ConnectionHandle GetConnectionHandle(const mxArray *pArray, bool bAllowNullHandle=false) {
    	// Strict typing! Make sure that the parameter has a valid type (scalar + handle datatype)
    	if (matlabIsScalar(pArray) && (mxGetClassID(pArray) == CONNECTIONHANDLE_CLASS_ID)) {
    		ConnectionHandle hHandle = *((ConnectionHandle*) mxGetData(pArray));
    		if ((hHandle >= 0) && (hHandle <= VAMATLAB_MAX_CONNECTIONS)) {
    			if (g_vpConnections[hHandle] || ((hHandle == 0) && bAllowNullHandle))
    				return hHandle;
    		}
    	}
    
    	VA_EXCEPT1("Invalid connection handle");
    	return NULL;
    }
    
    // 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
    void vCheckInputArguments(int nrhs, int iRequiredNumArgs) {
    	if (nrhs != iRequiredNumArgs) {
    		switch (iRequiredNumArgs) {
    		case 0: VA_EXCEPT1("This function does not take any arguments");
    		case 1: VA_EXCEPT1("This function takes exactly one argument");
    		case 2: VA_EXCEPT1("This function takes exactly two arguments");
    		case 3: VA_EXCEPT1("This function takes exactly three arguments");
    		case 4: VA_EXCEPT1("This function takes exactly four arguments");
    		case 5: VA_EXCEPT1("This function takes exactly five arguments");
    		case 6: VA_EXCEPT1("This function takes exactly six arguments");
    		// Do we need more?
    		default:
    			{
    				char buf[64];
    				sprintf_s(buf, 64, "This function takes exactly %d arguments", iRequiredNumArgs);
    				VA_EXCEPT1(buf);
    			}
    		}
    	}
    }
    
    // Displays information in the executable in Matlab
    void banner()
    {
    	mexPrintf("\n---------------------------------------------------------------------------------------------------\n\n");
    	mexPrintf("    VVV        VVV A          Virtual Acoustics (VA)\n");
    	mexPrintf("     VVV      VVV AAA         Real-time auralization for acoustic virtual environments\n");
    #if VAMATLAB_INTEGRATED == 1
    	mexPrintf("      VVV    VVV   AAA        VA Matlab with integrated VA core, version %s.%s\n", VAMATLAB_VERSION_MAJOR, VAMATLAB_VERSION_MINOR );
    #else
    	mexPrintf("      VVV    VVV   AAA        VA Matlab network client, version %s.%s\n", VAMATLAB_VERSION_MAJOR, VAMATLAB_VERSION_MINOR );
    #endif
    	mexPrintf("       VVV  VVV     AAA       (c) Copyright 2015-today, Institute of Technical Acoustics (ITA)\n");
    	mexPrintf("        VVVVVV       AAA      RWTH Aachen University, http://www.akustik.rwth-aachen.de\n");
    	mexPrintf("         VVVV         AAA     Distribution prohibited.\n");
    	mexPrintf("\n---------------------------------------------------------------------------------------------------\n\n");
    }
    
    // Helper macro
    #define REQUIRE_INPUT_ARGS(N) vCheckInputArguments(nrhs, N)
    
    /* +------------------------------------------------------+
       |                                                      |
       |   MEX Entry function                                 |
       |                                                      |
       +------------------------------------------------------+ */
    
    void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	if( g_bFirst )
    	{
    		g_bFirst = false;
    #ifdef VAMATLAB_SHOW_BANNER
    		banner();
    #endif
    	}
    
    	// At least one argument must be specified
    	if( nrhs < 1 )
    		mexErrMsgTxt( "Command argument expected" );
    
    	try
    	{
    		std::string sCommand = matlabGetString( prhs[0], "command" );
    
    		// 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
    		( *it->second.pAddr )( nlhs, plhs, nrhs-1, &prhs[1] );
    	}
    	catch( CVAException& e )
    	{
    		mexErrMsgTxt( e.GetErrorMessage().c_str() );
    	}
    	catch( ... )
    	{
    		mexErrMsgTxt( "An internal error occured - Please contact the developer" );
    	}
    }
    
    
    /* +------------------------------------------------------+
       |                                                      |
       |   Command functions                                  |
       |                                                      |
       +------------------------------------------------------+ */
    
    // Reflexion function. Returns cell-array of structs with information on the command functions.
    // Used for code generation of the Matlab MEX facade class [private]
    
    REGISTER_PRIVATE_FUNCTION(enumerateFunctions);
    
    void enumerateFunctions(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    	// Count public functions
    	mwSize nPublicFuncs = 0;
    	for (FunctionMapIterator it=g_mFunctionMap.begin(); it!=g_mFunctionMap.end(); ++it)
    		if (it->second.bPublic) nPublicFuncs++;
    
    	const mwSize nFields = 5;
    	const char* ppszFieldNames[] = {"name", "inargs", "outargs", "desc", "doc"};
    
    	mxArray* pStruct = mxCreateStructMatrix(1, nPublicFuncs, nFields, ppszFieldNames);
    	plhs[0] = pStruct;
    	
    	mwIndex i=0;
    	for (FunctionMapIterator it=g_mFunctionMap.begin(); it!=g_mFunctionMap.end(); ++it) {
    		if (!it->second.bPublic) continue;
    
    		// Input arguments
    		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()));
    
    		i++;
    	}
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PRIVATE_FUNCTION( getVersion );
    void getVersion( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	std::stringstream ss;
    	ss << "VAMatlab " << VAMATLAB_VERSION_MAJOR << "." << VAMATLAB_VERSION_MINOR;
    #ifdef DEBUG
    	ss << " (debug)";
    #else
    	ss << " (release)";
    #endif
    
    	if( nlhs == 1 )
    		plhs[0] = mxCreateString( ss.str().c_str() );
    	else
    		mexPrintf( "%s", ss.str().c_str() );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PRIVATE_FUNCTION( setVerboseMode );
    void setVerboseMode( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	
    	REQUIRE_INPUT_ARGS(1);
    	
    	std::string sMode = matlabGetString(prhs[0], "mode");
    	std::transform(sMode.begin(), sMode.end(), sMode.begin(), toupper);
    
    	if (sMode == "QUIET") {
    		g_iVerboseLevel = VERBOSE_LEVEL_QUIET;
    		return;
    	}
    
    	if (sMode == "NORMAL") {
    		g_iVerboseLevel = VERBOSE_LEVEL_NORMAL;
    		return;
    	}
    
    	VA_EXCEPT1("Invalid verbose mode");
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PRIVATE_FUNCTION(isConnected);
    
    #if VAMATLAB_INTEGRATED == 1
    
    void isConnected(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	plhs[0] = mxCreateLogicalScalar(true);
    };
    
    #else // VAMATLAB_INTEGRATED
    
    void isConnected(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0], true);
    	if (hHandle == 0) {
    		plhs[0] = mxCreateLogicalScalar(false);
    		return;
    	}
    
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	bool bConnected = pConnection->pClient->IsConnected();
    	plhs[0] = mxCreateLogicalScalar(bConnected);
    };
    
    #endif // VAMATLAB_INTEGRATED
    
    // ------------------------------------------------------------
    
    REGISTER_PRIVATE_FUNCTION(connect);
    
    #if VAMATLAB_INTEGRATED == 1
    
    void connect(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    	
    	// Always connection ID 1
    	ConnectionHandle hHandle = 1;
    
    	if (g_iConnectionsEstablished==0) {
    		try {
    			std::string sPath = getDirectoryFromPath( VACore::GetCoreLibFilename() );
    			std::string sConfigFile = combinePath( sPath, VA_DEFAULT_CONFIGFILE );
    			g_pOwnCore = VACore::CreateCoreInstance(sConfigFile);
    			g_pOwnCore->Initialize();
    		} catch (CVAException& e) {
    			delete g_pOwnCore;
    			g_pOwnCore = NULL;
    
    			char buf[4096];
    			sprintf_s(buf, 4096, "Failed to initialize VACore. %s.", e.GetErrorMessage().c_str());
    			mexErrMsgTxt(buf);
    		} catch (...) {
    			delete g_pOwnCore;
    			g_pOwnCore = NULL;
    
    			mexErrMsgTxt("Failed to initialize VACore");
    		}
    
    		mexPrintf("VACore initialized\n");
    
    		// First connection = Dummy connection to internal core
    		g_oDummyConnection.pClient = NULL;
    		g_oDummyConnection.pCoreInterface = g_pOwnCore;
    		g_vpConnections[hHandle] = &g_oDummyConnection;
    	}
    
    	++g_iConnectionsEstablished;
    
    	// Return the handle
    	plhs[0] = matlabCreateID(hHandle);
    }
    
    #else // VAMATLAB_INTEGRATED
    
    void connect(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    	
    	std::string sRemoteAddress = matlabGetString( prhs[0], "address" );
    
    	std::string sAddress;
    	int iPort;
    	SplitServerString(sRemoteAddress, sAddress, iPort);
    
    	if( g_iConnectionsEstablished == VAMATLAB_MAX_CONNECTIONS )
    	{
    		VA_EXCEPT1("Maximum number of connections reached. Close another opened connection first.");
    		return;
    	}
    
    	CVAMatlabConnection* pConnection = new CVAMatlabConnection;
    	// TODO: pConnection->pClient->AttachEventHandler(&g_oNetHandler);
    	
    	try
    	{
    		pConnection->pClient->Initialize( sAddress, iPort, IVANetClient::EXC_CLIENT_THROW, false );
    
    		if( !pConnection->pClient->IsConnected() )
    		{
    			// TODO: Delete object. Here were some error with double destruction. Exception in destr?
    			std::stringstream ss;
    			ss << "Connection to server \"" << sAddress << "\" failed";
    			VA_EXCEPT1(ss.str());
    			return;
    		}
    
    		pConnection->pCoreInterface = pConnection->pClient->GetCoreInstance();
    		pConnection->pVAMatlabTracker->pVACore = pConnection->pCoreInterface;
    
    		CVACoreVersionInfo oRemoteCoreVersion;
    		pConnection->pCoreInterface->GetVersionInfo( &oRemoteCoreVersion );
    
    		CVANetVersionInfo oNetVersion;
    		GetVANetVersionInfo( &oNetVersion );
    	}
    	catch (...)
    	{
    		delete pConnection;
    		throw;
    	}
    
    	ConnectionHandle hHandle = GenerateConnectionHandle();
    	g_vpConnections[hHandle] = pConnection;
    	++g_iConnectionsEstablished;
    
    	// Return the handle
    	plhs[0] = matlabCreateID(hHandle);
    
    	INFO("Connection to VA server \"%s\" established (connection handle: %d)\n",
    		 pConnection->pClient->GetServerAddress().c_str(), hHandle);
    }
    
    #endif // VAMATLAB_INTEGRATED
    
    // ------------------------------------------------------------
    
    REGISTER_PRIVATE_FUNCTION(disconnect);
    
    #if VAMATLAB_INTEGRATED == 1
    
    void disconnect(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	// Nothing to do ... Dummy function ...
    	if (g_iConnectionsEstablished < 1) {
    		VA_EXCEPT1("No connections established");
    		return;
    	}
    
    	--g_iConnectionsEstablished;
    	g_vpConnections[1] = NULL;
    
    	if (g_iConnectionsEstablished == 0) {
    		// Aufrumen
    		try {
    			g_pOwnCore->Finalize();
    			delete g_pOwnCore;
    			g_pOwnCore = NULL;
    		} catch (CVAException& e) {
    			delete g_pOwnCore;
    			g_pOwnCore = NULL;
    
    			char buf[4096];
    			sprintf_s(buf, 4096, "Failed to finalize VACore. %s.", e.GetErrorMessage().c_str());
    			mexErrMsgTxt(buf);
    
    		} catch (...) {
    			delete g_pOwnCore;
    			g_pOwnCore = NULL;
    
    			mexErrMsgTxt("Failed to finalize VACore. An unknown error occured.");
    		}
    
    		mexPrintf("VACore finalized\n");
    	}
    }
    
    #else // VAMATLAB_INTEGRATED
    
    void disconnect(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0], true);
    	if (hHandle == 0) return;
    
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sAddr(pConnection->pClient->GetServerAddress());
    
    	g_vpConnections[hHandle] = NULL;
    	--g_iConnectionsEstablished;
    	delete pConnection;
    
    	INFO("Disconnected from VA server \"%s\" (connection handle: %d)\n",
    		 sAddr.c_str(), hHandle);
    }
    
    #endif // VAMATLAB_INTEGRATED
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getServerAddress, "Returns for an opened connection the server it is connected to", "");
    DECLARE_FUNCTION_OUTARG(getServerAddress, addr, "string", "Server address");
    
    #if VAMATLAB_INTEGRATED == 1
    
    void getServerAddress(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	// We not really have a connection. But definitely the core is on this machine... :-)
    	prhs[0] = mxCreateString("localhost");
    }
    
    
    #else // VAMATLAB_INTEGRATED
    
    void getServerAddress(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	prhs[0] = mxCreateString(pConnection->pClient->GetServerAddress().c_str());
    }
    
    #endif // VAMATLAB_INTEGRATED
    
    
    // -------------------------- TRACKER ----------------------------------
    
    REGISTER_PRIVATE_FUNCTION( ConnectTracker );
    DECLARE_FUNCTION_OPTIONAL_INARG( ConnectTracker, serverIP, "string", "Server IP", "''" );
    DECLARE_FUNCTION_OPTIONAL_INARG( ConnectTracker, localIP, "string", "Local IP", "''" );
    void ConnectTracker( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	if( nrhs == 0 )
    		VA_EXCEPT2( INVALID_PARAMETER, "Missing VA connection handle in ConnectTracker" );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	CVAMatlabTracker* pTracker = pConnection->pVAMatlabTracker;
    	
    	std::string sServerAdress = "127.0.0.1";
    	if( nrhs > 1 )
    		sServerAdress = std::string( matlabGetString( prhs[1], "serverIP" ) );
    	
    	std::string sLocalAdress = "127.0.0.1";
    	if( nrhs > 2 )
    		sLocalAdress = std::string( matlabGetString( prhs[2], "localIP" ) );
    
    	if( pTracker->Initialize( sServerAdress, sLocalAdress ) == false )
    		VA_EXCEPT2( INVALID_PARAMETER, "Could not initialize connection to tracker with remote adress '" + sServerAdress 
    		+ "' and local adress '" + sLocalAdress + "'" );
    }
    
    REGISTER_PRIVATE_FUNCTION( DisconnectTracker );
    void DisconnectTracker( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 1 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	if( pConnection->pVAMatlabTracker->Uninitialize() == false )
    		VA_EXCEPT2( INVALID_PARAMETER, "Could not disconnect from tracker" );
    
    	pConnection->pVAMatlabTracker->Reset();
    }
    
    REGISTER_PRIVATE_FUNCTION( IsTrackerConnected );
    DECLARE_FUNCTION_OUTARG( IsTrackerConnected, connected, "logical scalar", "True if a tracker connection is established" );
    void IsTrackerConnected( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 1 );
    	
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	CVAMatlabTracker* pTracker = pConnection->pVAMatlabTracker;
    	
    	bool bIsConnected = pTracker->IsConnected();
    	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." );
    		}
    	}
    
    	plhs[0] = mxCreateLogicalScalar( bIsConnected );
    
    	return;
    }
    
    REGISTER_PRIVATE_FUNCTION( SetTrackedListener );
    DECLARE_FUNCTION_REQUIRED_INARG( SetTrackedListener, listenerID, "scalar number", "Listener ID" );
    void SetTrackedListener( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar( prhs[1], "listenerID" );
    	pConnection->pVAMatlabTracker->iTrackedListenerID = iListenerID;
    }
    
    REGISTER_PRIVATE_FUNCTION( SetTrackedSource );
    DECLARE_FUNCTION_REQUIRED_INARG( SetTrackedSource, sourceID, "scalar number", "Source ID" );
    void SetTrackedSource( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSourceID = matlabGetIntegerScalar( prhs[1], "sourceID" );
    	if( pConnection->pVAMatlabTracker->iTrackedListenerID != -1 )
    		VA_EXCEPT2( MODAL_ERROR, "Can not use a tracked sound source if a listener is already tracked by this connection" );
    	pConnection->pVAMatlabTracker->iTrackedSourceID = iSourceID;
    }
    
    REGISTER_PRIVATE_FUNCTION( SetRigidBodyIndex );
    DECLARE_FUNCTION_REQUIRED_INARG( SetRigidBodyIndex, index, "scalar number", "Rigid body index (default is 1)" );
    void SetRigidBodyIndex( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iTrackedRigidBodyIndex = matlabGetIntegerScalar( prhs[1], "index" );
    
    	pConnection->pVAMatlabTracker->iRigidBodyIndex = iTrackedRigidBodyIndex;
    }
    
    REGISTER_PRIVATE_FUNCTION( SetRigidBodyTranslation );
    DECLARE_FUNCTION_REQUIRED_INARG( SetRigidBodyTranslation, offset, "real 1x3", "Rigid body position offset" );
    void SetRigidBodyTranslation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double x, y, z;
    	matlabGetRealVector3( prhs[1], "offset", x, y, z );
    
    	pConnection->pVAMatlabTracker->vTranslation = VistaVector3D( float( x ), float( y ), float( z ) );
    }
    
    REGISTER_PRIVATE_FUNCTION( SetRigidBodyRotation );
    DECLARE_FUNCTION_REQUIRED_INARG( SetRigidBodyRotation, rotation, "real 1x4", "Rigid body rotation (quaternion values with w (real), i, j, k)" );
    void SetRigidBodyRotation( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double w, i, j, k;
    	matlabGetQuaternion( prhs[1], "rotation", w, i, j, k );
    
    	pConnection->pVAMatlabTracker->qRotation = VistaQuaternion( float( i ), float( j ), float( k ), float( w ) );
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Base functions                                         | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PRIVATE_FUNCTION(getServerState);
    
    void getServerState(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	plhs[0] = matlabCreateID( pConnection->pCoreInterface->GetState() );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(reset, "Resets the VA server", "");
    
    #if VAMATLAB_INTEGRATED == 1
    
    void reset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	INFO("Resetting VA core\n");
    
    	g_pOwnCore->Reset();
    }
    
    #else // VAMATLAB_INTEGRATED
    
    void reset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	INFO("Resetting VA server \"%s\" (connection handle: %d)\n",
    		 pConnection->pClient->GetServerAddress().c_str(), hHandle);
    
    	pConnection->pCoreInterface->Reset();
    }
    
    #endif // VAMATLAB_INTEGRATED
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Module interface                                       | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION( enumerateModules, "Enumerates internal modules of the VA server", "" );
    DECLARE_FUNCTION_OUTARG( enumerateModules, modules, "cell-array of struct-1x1", "Module informations (names, descriptions, etc.)" );
    void enumerateModules( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	REQUIRE_INPUT_ARGS( 1 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector< CVAModuleInfo > v;
    	pConnection->pCoreInterface->EnumerateModules( v );
    
    	const size_t nDims = int( v.size() );
    	const int nFields = 2;
    	const char* ppszFieldNames[] = { "name", "desc" };
    	plhs[0] = mxCreateStructArray( 1, &nDims, nFields, ppszFieldNames );
    
    	for( size_t i=0; i < nDims; i++ )
    	{
    		mxSetField( plhs[0], i, ppszFieldNames[0], mxCreateString( v[i].sName.c_str() ) );
    		mxSetField( plhs[0], i, ppszFieldNames[1], mxCreateString( v[i].sDesc.c_str() ) );
    	}
    
    	return;
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( callModule, "Calls an internal module of the VA server", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( callModule, module, "string", "Module name" );
    DECLARE_FUNCTION_REQUIRED_INARG( callModule, mstruct, "struct", "Matlab structure with key-value content" );
    DECLARE_FUNCTION_OUTARG( callModule, ret, "struct-1x1", "Struct containing the return values" );
    void callModule( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	if( nrhs != 3 )
    		VA_EXCEPT2( INVALID_PARAMETER, "This function takes three arguments (connection, module, params)" );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sModuleName = matlabGetString( prhs[1], "module" );
    	CVAStruct oArgs = matlabGetStruct( prhs[2], "mstruct" );
    
    	CVAStruct oReturn;
    
    	pConnection->pCoreInterface->CallModule( sModuleName, oArgs, oReturn );
    
    	if( nlhs == 0 )
    		return;
    	
    	if( nlhs == 1 )
    	{
    		mxArray* pReturnArray = matlabCreateStruct( oReturn );
    		plhs[0] = pReturnArray;
    	}
    	else
    	{
    		VA_EXCEPT2( INVALID_PARAMETER, "Too many left-hand-side return arguments given, this function returns a single argument (as struct) or nothing" );
    	}
    
    	return;
    }
    
    REGISTER_PUBLIC_FUNCTION( addSearchPath, "adds a search path at core side", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( addSearchPath, path, "string", "Relative or absolute path" );
    DECLARE_FUNCTION_OUTARG( addSearchPath, valid, "logical scalar", "True, if path at core side valid" );
    void addSearchPath( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sPath = matlabGetString( prhs[1], "path" );
    	bool bValid = pConnection->pCoreInterface->AddSearchPath( sPath );
    	plhs[0] = mxCreateLogicalScalar( bValid );
    
    	return;
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Directivities                                          | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(loadDirectivity, "Loads a directivity from a file", "");
    DECLARE_FUNCTION_REQUIRED_INARG(loadDirectivity, filename, "string", "Filename");
    DECLARE_FUNCTION_OPTIONAL_INARG(loadDirectivity, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(loadDirectivity, directivityID, "integer-1x1", "Directivity ID");
    
    void loadDirectivity(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sFilename = matlabGetString(prhs[1], "filename");
    	std::string sName = matlabGetString(prhs[2], "Name");
    
    	int iDirectivityID = pConnection->pCoreInterface->LoadDirectivity(sFilename, sName);
    	plhs[0] = matlabCreateID(iDirectivityID);
    
    	INFO("Loaded directivity \"%s\" successfully loaded (id: %d)\n", sFilename.c_str(), hHandle);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(freeDirectivity, "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(freeDirectivity, directivityID, "integer-1x1", "Directivity ID");
    DECLARE_FUNCTION_OUTARG(freeDirectivity, result, "logical-1x1", "Directivity freed?");
    
    void freeDirectivity(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iDirectivityID = matlabGetIntegerScalar(prhs[1], "directivityID");
    
    	bool bResult = pConnection->pCoreInterface->FreeDirectivity(iDirectivityID);
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getDirectivityInfo, "Returns information on a loaded directivity", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getDirectivityInfo, directivityID, "integer-1x1", "Directivity ID");
    DECLARE_FUNCTION_OUTARG(getDirectivityInfo, info, "struct-1x1", "Information struct (name, filename, resolution, etc.)");
    
    void getDirectivityInfo(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iDirectivityID = matlabGetIntegerScalar(prhs[1], "directivityID");
    	CVADirectivityInfo di = pConnection->pCoreInterface->GetDirectivityInfo(iDirectivityID);
    	plhs[0] = matlabCreateDirectivityInfo(di);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getDirectivityInfos, "Returns information on all loaded directivities", "");
    DECLARE_FUNCTION_OUTARG(getDirectivityInfos, info, "cell-array of struct-1x1", "Information structs (name, filename, resolution, etc.)");
    
    void getDirectivityInfos(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<CVADirectivityInfo> v;
    	pConnection->pCoreInterface->GetDirectivityInfos(v);
    
    	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]));
    
    	plhs[0] = pCell;
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Head-related impulse responses (HRIRs)                 | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(loadHRIRDataset, "Loads a HRIR dataset from a file", "");
    DECLARE_FUNCTION_REQUIRED_INARG(loadHRIRDataset, filename, "string", "Filename");
    DECLARE_FUNCTION_OPTIONAL_INARG(loadHRIRDataset, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(loadHRIRDataset, id, "integer-1x1", "HRIR dataset ID");
    
    void loadHRIRDataset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sFilename = matlabGetString(prhs[1], "filename");
    	std::string sName = matlabGetString(prhs[2], "name");
    
    	int iHRIRID = pConnection->pCoreInterface->LoadHRIRDataset(sFilename, sName);
    
    	plhs[0] = matlabCreateID(iHRIRID);
    
    	INFO("HRIR dataset '%s' successfully loaded (id: %d)\n", sFilename.c_str(), iHRIRID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(freeHRIRDataset, "Frees a loaded HRIR dataset", "This is only possible if the HRIR dataset is not in use. Otherwise the method will do nothing.");
    DECLARE_FUNCTION_REQUIRED_INARG(freeHRIRDataset, hrirID, "integer-1x1", "HRIR dataset ID");
    DECLARE_FUNCTION_OUTARG(freeHRIRDataset, result, "logical-1x1", "HRIR dataset freed?");
    
    void freeHRIRDataset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iHRIRID = matlabGetIntegerScalar(prhs[1], "hrirID");
    
    	bool bResult = pConnection->pCoreInterface->FreeHRIRDataset(iHRIRID);
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getHRIRDatasetInfo, "Returns information on a loaded HRIR dataset", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getHRIRDatasetInfo, hrirID, "integer-1x1", "HRIR dataset ID");
    DECLARE_FUNCTION_OUTARG(getHRIRDatasetInfo, info, "struct-1x1", "Information structs (name, filename, resolution, etc.)");
    
    void getHRIRDatasetInfo(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iHRIRID = matlabGetIntegerScalar(prhs[1], "hrirID");
    	CVAHRIRInfo hi = pConnection->pCoreInterface->GetHRIRInfo(iHRIRID);
    	plhs[0] = matlabCreateHRIRInfo(hi);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getHRIRDatasetInfos, "Returns information on all loaded HRIR datasets", "");
    DECLARE_FUNCTION_OUTARG(getHRIRDatasetInfos, info, "cell-array of struct-1x1", "Information structs (name, filename, resolution, etc.)");
    
    void getHRIRDatasetInfos(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<CVAHRIRInfo> v;
    	pConnection->pCoreInterface->GetHRIRInfos(v);
    
    	const mwSize dims[2] = { 1,  v.size() };
    	mxArray* pCell = mxCreateCellArray(2, dims);
    	for (size_t i=0; i<v.size(); i++)
    		mxSetCell(pCell, i,  matlabCreateHRIRInfo(v[i]));
    
    	plhs[0] = pCell;
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Sounds                                                 | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(loadSound, "Loads a sound from an audiofile", "Note: The audiofile must be mono");
    DECLARE_FUNCTION_REQUIRED_INARG(loadSound, filename, "string", "Filename");
    DECLARE_FUNCTION_OPTIONAL_INARG(loadSound, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(loadSound, id, "integer-1x1", "Sound ID");
    
    void loadSound(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sFilename = matlabGetString(prhs[1], "filename");
    	std::string sName = matlabGetString(prhs[2], "name");
    
    	int iSoundID = pConnection->pCoreInterface->LoadSound(sFilename, sName);
    
    	plhs[0] = matlabCreateID(iSoundID);
    
    	INFO("Sound '%s' successfully loaded (id: %d)\n", sFilename.c_str(), iSoundID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(freeSound, "Frees a loaded sound", "");
    DECLARE_FUNCTION_REQUIRED_INARG(freeSound, soundID, "integer-1x1", "Sound ID");
    DECLARE_FUNCTION_OUTARG(freeSound, result, "logical-1x1", "Sound freed?");
    
    void freeSound(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundID = matlabGetIntegerScalar(prhs[1], "soundID");
    
    	bool bResult = pConnection->pCoreInterface->FreeSound(iSoundID);
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundInfo, "Returns information on a loaded sound", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundInfo, soundID, "integer-1x1", "Sound ID");
    DECLARE_FUNCTION_OUTARG(getSoundInfo, info, "struct-1x1", "Information struct (name, filename, length, etc.)");
    
    void getSoundInfo(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundID = matlabGetIntegerScalar(prhs[1], "soundID");
    	CVASoundInfo si = pConnection->pCoreInterface->GetSoundInfo(iSoundID);
    	plhs[0] = matlabCreateSoundInfo(si);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundInfos, "Returns information on all loaded sounds", "");
    DECLARE_FUNCTION_OUTARG(getSoundInfos, info, "cell-array of struct-1x1", "Information structs (name, filename, length, etc.)");
    
    void getSoundInfos(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<CVASoundInfo> v;
    	pConnection->pCoreInterface->GetSoundInfos(v);
    
    	const mwSize dims[2] = { 1,  v.size() };
    	mxArray* pCell = mxCreateCellArray(2, dims);
    	for (size_t i=0; i<v.size(); i++)
    		mxSetCell(pCell, i,  matlabCreateSoundInfo(v[i]));
    
    	plhs[0] = pCell;
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(playSound, "Plays a sound", "");
    DECLARE_FUNCTION_REQUIRED_INARG(playSound, soundID, "integer-1x1", "Sound ID");
    DECLARE_FUNCTION_OPTIONAL_INARG(playSound, volume, "double-1x1", "Volume [factor]", "1");
    DECLARE_FUNCTION_OUTARG(playSound, id, "integer-1x1", "Playback ID");
    
    void playSound(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundID = matlabGetIntegerScalar(prhs[1], "soundID");
    	// TODO: Check availability of 2nd parameter
    	double dVolume(1);
    	if (nlhs >= 2) matlabGetRealScalar(prhs[2], "volume");
    
    	int iPlaybackID = pConnection->pCoreInterface->PlaySound(iSoundID, dVolume);
    
    	plhs[0] = matlabCreateID(iPlaybackID);
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Signal sources                                         | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(createAudiofileSignalSource, "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(createAudiofileSignalSource, filename, "string", "Filename");
    DECLARE_FUNCTION_OPTIONAL_INARG(createAudiofileSignalSource, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(createAudiofileSignalSource, signalSourceID, "string", "Signal source ID");
    
    void createAudiofileSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sFilename = matlabGetString(prhs[1], "filename");
    	std::string sName = matlabGetString(prhs[2], "name");
    
    	std::string sID = pConnection->pCoreInterface->CreateAudiofileSignalSource(sFilename, sName);
    	plhs[0] = mxCreateString(sID.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(createEngineSignalSource, "Creates an engine signal source", "");
    DECLARE_FUNCTION_OPTIONAL_INARG(createEngineSignalSource, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(createEngineSignalSource, signalSourceID, "string", "Signal source ID");
    
    void createEngineSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sName = matlabGetString(prhs[1], "name");
    
    	std::string sID = pConnection->pCoreInterface->CreateEngineSignalSource( sName );
    	plhs[0] = mxCreateString( sID.c_str() );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(createSequencerSignalSource, "Creates a sequencer signal source", "");
    DECLARE_FUNCTION_OPTIONAL_INARG(createSequencerSignalSource, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(createSequencerSignalSource, signalSourceID, "string", "Signal source ID");
    
    void createSequencerSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sName = matlabGetString(prhs[1], "name");
    
    	std::string sID = pConnection->pCoreInterface->CreateSequencerSignalSource(sName);
    	plhs[0] = mxCreateString(sID.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(createNetworkStreamSignalSource, "Creates a signal source which receives audio samples via network", "");
    DECLARE_FUNCTION_REQUIRED_INARG(createNetworkStreamSignalSource, address, "string", "Hostname or IP address of the audio streaming server");
    DECLARE_FUNCTION_REQUIRED_INARG(createNetworkStreamSignalSource, port, "integer-1x1", "Server port");
    DECLARE_FUNCTION_OPTIONAL_INARG(createNetworkStreamSignalSource, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OUTARG(createNetworkStreamSignalSource, signalSourceID, "string", "Signal source ID");
    
    void createNetworkStreamSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sAddress = matlabGetString(prhs[1], "address");
    	int iPort = matlabGetIntegerScalar(prhs[2], "port");
    	std::string sName = matlabGetString(prhs[3], "name");
    
    	std::string sID = pConnection->pCoreInterface->CreateNetworkStreamSignalSource(sAddress, iPort, sName);
    	plhs[0] = mxCreateString(sID.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(deleteSignalSource, "Deletes a signal source", "A signal source can only be deleted, if it is not in use.");
    DECLARE_FUNCTION_REQUIRED_INARG(deleteSignalSource, signalSourceID, "string", "Signal source ID");
    DECLARE_FUNCTION_OUTARG(deleteSignalSource, result, "logical-1x1", "Signal source deleted?");
    
    void deleteSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString(prhs[1], "signalSourceID");
    
    	bool bResult = pConnection->pCoreInterface->DeleteSignalSource(sID);
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSignalSourceInfo, "Returns information on signal source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSignalSourceInfo, signalSourceID, "string", "Signal source ID");
    DECLARE_FUNCTION_OUTARG(getSignalSourceInfo, info, "struct-1x1", "Information structs (id, name, type, etc.)");
    
    void getSignalSourceInfo(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string iSourceID = matlabGetString(prhs[1], "signalSourceID");
    	CVASignalSourceInfo ssi = pConnection->pCoreInterface->GetSignalSourceInfo(iSourceID);
    	plhs[0] = matlabCreateSignalSourceInfo(ssi);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSignalSourceInfos, "Returns information on all existing signal sources", "");
    DECLARE_FUNCTION_OUTARG(getSignalSourceInfos, info, "cell-array of struct-1x1", "Information structs (id, name, type, etc.)");
    
    void getSignalSourceInfos(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<CVASignalSourceInfo> v;
    	pConnection->pCoreInterface->GetSignalSourceInfos(v);
    
    	const mwSize dims[2] = { 1,  v.size() };
    	mxArray* pCell = mxCreateCellArray(2, dims);
    	for (size_t i=0; i<v.size(); i++)
    		mxSetCell(pCell, i,  matlabCreateSignalSourceInfo(v[i]));
    
    	plhs[0] = pCell;
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( getAudiofileSignalSourcePlaybackState, "Returns the playback state of an audiofile signal source. Available modes: PLAYING, STOPPED, PAUSED", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( getAudiofileSignalSourcePlaybackState, signalSourceID, "string", "Signal source ID" );
    DECLARE_FUNCTION_OUTARG( getAudiofileSignalSourcePlaybackState, playState , "string", "Playback state" );
    
    void getAudiofileSignalSourcePlaybackState( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(2);
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	std::string sSignalSourceID = matlabGetString( prhs[1], "signalSourceID" );
    	int iPlayState = pConnection->pCoreInterface->GetAudiofileSignalSourcePlaybackState( sSignalSourceID );
    	std::string sPlayState = pConnection->pCoreInterface->GetPlaybackStateStr( iPlayState );
    	plhs[0] = mxCreateString( sPlayState.c_str() );
    
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( setAudiofileSignalSourcePlaybackAction, "Change the playback state of an audiofile signal source. Available actions: PLAY STOP PAUSE", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( setAudiofileSignalSourcePlaybackAction, signalSourceID, "string", "Signal source ID" );
    DECLARE_FUNCTION_REQUIRED_INARG( setAudiofileSignalSourcePlaybackAction, playAction, "string", "Playback action" );
    void setAudiofileSignalSourcePlaybackAction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(3);
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sSignalSourceID = matlabGetString( prhs[1], "signalSourceID" );
    	std::string sPlayAction = matlabGetString( prhs[2], "playAction" );
    	int iPlayAction = IVACore::ParsePlaybackAction( sPlayAction  );
    	pConnection->pCoreInterface->SetAudiofileSignalSourcePlaybackAction( sSignalSourceID, iPlayAction );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( setAudiofileSignalSourceIsLooping, "Change the playback state of an audiofile signal source. Available actions: PLAY STOP PAUSE", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( setAudiofileSignalSourceIsLooping, signalSourceID, "string", "Signal source ID" );
    DECLARE_FUNCTION_REQUIRED_INARG( setAudiofileSignalSourceIsLooping, isLooping, "logical", "Set looping enabled/disabled" );
    void setAudiofileSignalSourceIsLooping( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(3);
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sSignalSourceID = matlabGetString( prhs[1], "signalSourceID" );
    	bool bIsLooping = matlabGetBoolScalar( prhs[2], "isLooping" );
    	pConnection->pCoreInterface->SetAudiofileSignalSourceIsLooping( sSignalSourceID, bIsLooping );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( getAudiofileSignalSourceIsLooping, "Returns the playback state of an audiofile signal source. Available modes: PLAYING, STOPPED, PAUSED", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( getAudiofileSignalSourceIsLooping, signalSourceID, "string", "Signal source ID" );
    DECLARE_FUNCTION_OUTARG( getAudiofileSignalSourceIsLooping, isLooping , "logical-1x1", "Looping enabled/disabled" );
    
    void getAudiofileSignalSourceIsLooping( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(2);
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	std::string sSignalSourceID = matlabGetString( prhs[1], "signalSourceID" );
    	bool bIsLooping = pConnection->pCoreInterface->GetAudiofileSignalSourceIsLooping( sSignalSourceID );
    	plhs[0] = mxCreateLogicalScalar( bIsLooping );
    
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setAudiofileSignalSourcePlayPosition, "Sets the playback position of an audiofile signal source.", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setAudiofileSignalSourcePlayPosition, signalSourceID, "string", "Signal source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setAudiofileSignalSourcePlayPosition, playPosition, "scalar", "Playback position [s]");
    
    void setAudiofileSignalSourcePlayPosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sSignalSourceID = matlabGetString(prhs[1], "signalSourceID");
    	double dPlaybackPosition = matlabGetRealScalar(prhs[2], "playPosition");
    	
    	pConnection->pCoreInterface->SetAudiofileSignalSourcePlaybackPosition(sSignalSourceID, dPlaybackPosition);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(addSoundPlayback, "Adds a sound playback for a sequencer signal source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(addSoundPlayback, signalSourceID, "string", "Sequencer signal source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(addSoundPlayback, soundID, "integer-1x1", "Sound ID");
    DECLARE_FUNCTION_REQUIRED_INARG(addSoundPlayback, flags, "integer-1x1", "Playback flags");
    DECLARE_FUNCTION_REQUIRED_INARG(addSoundPlayback, timecode, "double-1x1", "Playback time (expressed in core clock time, 0 => instant playback)");
    DECLARE_FUNCTION_OUTARG(addSoundPlayback, playbackID , "integer-1x1", "Playback ID");
    
    void addSoundPlayback(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(5);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString(prhs[1], "signalSourceID");
    	int iSoundID = matlabGetIntegerScalar(prhs[2], "soundID");
    	int iFlags = matlabGetIntegerScalar(prhs[3], "flags");
    	double dTimecode = matlabGetRealScalar(prhs[4], "timecode");
    
    	int iPlaybackID = pConnection->pCoreInterface->AddSoundPlayback(sID, iSoundID, iFlags, dTimecode);
    	plhs[0] = matlabCreateID(iPlaybackID); 
    }
    
    REGISTER_PUBLIC_FUNCTION(removeSoundPlayback, "Removes an existing sound playback from a sequencer signal source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(removeSoundPlayback, playbackID, "integer-1x1", "Playback ID");
    DECLARE_FUNCTION_OUTARG(removeSoundPlayback, result, "logical-1x1", "Playback removed?");
    
    // ------------------------------------------------------------
    
    void removeSoundPlayback(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iPlaybackID = matlabGetIntegerScalar(prhs[1], "playbackID");
    
    	bool bResult = pConnection->pCoreInterface->RemoveSoundPlayback(iPlaybackID);
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Synchronization functions                              | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION( isSceneLocked, "Is scene locked?", "");
    DECLARE_FUNCTION_OUTARG( isSceneLocked, result, "logical-1x1", "true, if within locked (synchronized) scene modification" );
    
    void isSceneLocked( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	bool bResult = pConnection->pCoreInterface->IsSceneLocked();
    	plhs[0] = mxCreateLogicalScalar( bResult );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( lockScene, "Locks the scene (modifications of scene can be applied synchronously)", "During a locked scene, no changes are directly applied. After unlocking, all modifications are syncrhonously applied." );
    void lockScene( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	REQUIRE_INPUT_ARGS(1);
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	pConnection->pCoreInterface->LockScene();
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( unlockScene, "Unlocks scene and applied synchronously modifications made", "returns state ID of the scene if successfully proceeded, -1 if not" );
    DECLARE_FUNCTION_OUTARG( unlockScene, newStateID, "integer-1x1", "" );
    void unlockScene( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(1);
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	int iNewStateID = pConnection->pCoreInterface->UnlockScene();
    	plhs[0] = matlabCreateID( iNewStateID );
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Sound sources                                          | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceIDs, "Returns the IDs of all sound sources in the scene", "");
    DECLARE_FUNCTION_OUTARG(getSoundSourceIDs, ids, "integer-1xN", "Vector containing the IDs");
    
    void getSoundSourceIDs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<int> v;
    	pConnection->pCoreInterface->GetSoundSourceIDs(v);
    	plhs[0] = matlabCreateIDList(v);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(createSoundSource, "Creates a sound source", "");
    DECLARE_FUNCTION_OPTIONAL_INARG(createSoundSource, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OPTIONAL_INARG(createSoundSource, auralizationMode, "string", "Auralization mode", "'default'");
    DECLARE_FUNCTION_OPTIONAL_INARG(createSoundSource, volume, "double-1x1", "Volume [factor]", "1");
    DECLARE_FUNCTION_OUTARG(createSoundSource, id, "integer-1x1", "Sound source ID");
    
    void createSoundSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sName = matlabGetString(prhs[1], "name");
    	std::string sAuralizationMode = matlabGetString(prhs[2], "auralizationMode");
    	int iAuralizationMode = IVACore::ParseAuralizationModeStr(sAuralizationMode);
    	double dVolume = matlabGetRealScalar(prhs[3], "volume");
    
    	int iSourceID = pConnection->pCoreInterface->CreateSoundSource(sName, iAuralizationMode, dVolume);
    	plhs[0] = matlabCreateID(iSourceID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( createSoundSourceExplicitRenderer, "Creates a sound source explicitly for a certain renderer", "");
    DECLARE_FUNCTION_REQUIRED_INARG( createSoundSourceExplicitRenderer, name, "string", "Name");
    DECLARE_FUNCTION_REQUIRED_INARG( createSoundSourceExplicitRenderer, renderer, "string", "Renderer identifier");
    DECLARE_FUNCTION_OUTARG( createSoundSourceExplicitRenderer, id, "integer-1x1", "Sound source ID");
    void createSoundSourceExplicitRenderer( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle( prhs[0] );
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sName = matlabGetString( prhs[1], "name" );
    	std::string sRendererID = matlabGetString( prhs[2], "renderer" );
    
    	int iSourceID = pConnection->pCoreInterface->CreateSoundSourceExplicitRenderer( sName, sRendererID );
    	plhs[0] = matlabCreateID( iSourceID );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(deleteSoundSource, "Deletes an existing sound source in the scene", "");
    DECLARE_FUNCTION_REQUIRED_INARG(deleteSoundSource, soundSourceID, "integer-1x1", "Sound source ID");
    
    void deleteSoundSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    
    	pConnection->pCoreInterface->DeleteSoundSource(iSoundSourceID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceName, "Returns name of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceName, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceName, name, "string", "Displayed name");
    
    void getSoundSourceName(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    
    	std::string sName = pConnection->pCoreInterface->GetSoundSourceName(iSoundSourceID);
    	plhs[0] = mxCreateString(sName.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceName, "Name", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceName, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceName, name, "string", "Displayed name");
    
    void setSoundSourceName(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	std::string sName = matlabGetString(prhs[2], "name");
    
    	pConnection->pCoreInterface->SetSoundSourceName(iSoundSourceID, sName);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceSignalSource, "Returns for a sound source, the attached signal source", "Note: This function returns an empty string, if no signal source is attached.");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceSignalSource, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceSignalSource, signalSourceID, "string", "Signal source ID");
    
    void getSoundSourceSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    
    	std::string sSignalSourceID = pConnection->pCoreInterface->GetSoundSourceSignalSource(iSoundSourceID);
    	plhs[0] = mxCreateString(sSignalSourceID.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceSignalSource, "Sets the signal source of a sound source", "Note: Passing an empty string removes the signal source");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceSignalSource, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceSignalSource, signalSourceID, "string", "Signal Source ID");
    
    void setSoundSourceSignalSource(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	std::string sSignalSourceID = matlabGetString(prhs[2], "signalSourceID");
    
    	pConnection->pCoreInterface->SetSoundSourceSignalSource(iSoundSourceID, sSignalSourceID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( removeSoundSourceSignalSource, "Removes the signal source of a sound source", "Note: will note remove the signal source from manager" );
    DECLARE_FUNCTION_REQUIRED_INARG( removeSoundSourceSignalSource, ID, "integer-1x1", "Sound source identifier");
    void removeSoundSourceSignalSource( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	int iID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	pConnection->pCoreInterface->RemoveSoundSourceSignalSource( iID );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceAuralizationMode, "Returns the auralization mode of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceAuralizationMode, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceAuralizationMode, auralizationMode, "string", "Auralization mode");
    
    void getSoundSourceAuralizationMode(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	int iAuralizationMode = pConnection->pCoreInterface->GetSoundSourceAuralizationMode(iSoundSourceID);
    	plhs[0] = mxCreateString( IVACore::GetAuralizationModeStr(iAuralizationMode, true).c_str() );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceAuralizationMode, "Returns the auralization mode of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceAuralizationMode, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceAuralizationMode, auralizationMode, "string", "Auralization mode");
    
    void setSoundSourceAuralizationMode(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	std::string sAuralizationMode = matlabGetString(prhs[2], "auralizationMode");
    
    	// Get the current auralization mode first for computing relative modes (+|-)
    	int iCurAuralizationMode = pConnection->pCoreInterface->GetSoundSourceAuralizationMode(iSoundSourceID);
    	int iNewAuralizationMode = IVACore::ParseAuralizationModeStr(sAuralizationMode, iCurAuralizationMode);
    
    	pConnection->pCoreInterface->SetSoundSourceAuralizationMode(iSoundSourceID, iNewAuralizationMode);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( getSoundSourceParameters, "Returns the current sound source parameters", "");
    DECLARE_FUNCTION_REQUIRED_INARG( getSoundSourceParameters, ID, "integer-1x1", "Sound source identifier");
    DECLARE_FUNCTION_REQUIRED_INARG( getSoundSourceParameters, args, "mstruct", "Requested parameters");
    DECLARE_FUNCTION_OUTARG( getSoundSourceParameters, params, "mstruct", "Parameters");
    void getSoundSourceParameters( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iID = matlabGetIntegerScalar( prhs[1], "ID" );
    	CVAStruct oArgs = matlabGetStruct( prhs[2], "args" );
    	CVAStruct oRet = pConnection->pCoreInterface->GetSoundSourceParameters( iID, oArgs );
    	plhs[0] = matlabCreateStruct( oRet );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( setSoundSourceParameters, "Sets sound source parameters", "");
    DECLARE_FUNCTION_REQUIRED_INARG( setSoundSourceParameters, ID, "integer-1x1", "Sound source identifier");
    DECLARE_FUNCTION_REQUIRED_INARG( setSoundSourceParameters, params, "mstruct", "Parameters");
    void setSoundSourceParameters( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iID = matlabGetIntegerScalar( prhs[1], "ID" );
    	CVAStruct oParams = matlabGetStruct( prhs[2], "params" );
    	pConnection->pCoreInterface->SetSoundSourceParameters( iID, oParams );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceDirectivity, "Returns the directivity of a sound source", "Note: If the sound source is not assigned a directivity, the methods returns -1.");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceDirectivity, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceDirectivity, directivityID, "integer-1x1", "Directivity ID");
    
    void getSoundSourceDirectivity(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	int iDirectivityID = pConnection->pCoreInterface->GetSoundSourceDirectivity(iSoundSourceID);
    
    	plhs[0] = matlabCreateID(iDirectivityID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceDirectivity, "Sets the directivity of a sound source", "Note: In order to set no directivity (omnidirectional source), you can pass -1 to the method.");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceDirectivity, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceDirectivity, directivityID, "integer-1x1", "Directivity ID");
    
    void setSoundSourceDirectivity(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	int iDirectivityID = matlabGetIntegerScalar(prhs[2], "directivityID");
    
    	pConnection->pCoreInterface->SetSoundSourceDirectivity(iSoundSourceID, iDirectivityID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceVolume, "Returns the volume of a sound source", "Note: The method returns the amplification factor (range [0,1], no Decibel values!)");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceVolume, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceVolume, volume, "double-1x1", "Volume");
    
    void getSoundSourceVolume(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    
    	double dVolume = pConnection->pCoreInterface->GetSoundSourceVolume(iSoundSourceID);
    	plhs[0] = mxCreateDoubleScalar(dVolume);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceVolume, "Sets the volume of a sound source", "Note: The volume is an amplification factor (range [0,1])");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceVolume, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceVolume, volume, "double-1x1", "Volume");
    
    void setSoundSourceVolume(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double dVolume = matlabGetRealScalar(prhs[2], "volume");
    
    	// TODO: Erweiterte Eingaben. Z.b. mit "+3db"
    	pConnection->pCoreInterface->SetSoundSourceVolume(iSoundSourceID, dVolume);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(isSoundSourceMuted, "Returns if a sound source is muted", "");
    DECLARE_FUNCTION_REQUIRED_INARG(isSoundSourceMuted, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(isSoundSourceMuted, result, "logical-1x1", "Muted?");
    
    void isSoundSourceMuted(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    
    	bool bResult = pConnection->pCoreInterface->IsSoundSourceMuted(iSoundSourceID);
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceMuted, "Sets a sound source muted or unmuted", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceMuted, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceMuted, muted, "logical-1x1", "Muted?");
    
    void setSoundSourceMuted(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	bool bMuted = matlabGetBoolScalar(prhs[2], "muted");
    
    	pConnection->pCoreInterface->SetSoundSourceMuted(iSoundSourceID, bMuted);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourcePosition, "Returns the position of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourcePosition, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePosition, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    
    void getSoundSourcePosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    
    	double x, y, z;
    	pConnection->pCoreInterface->GetSoundSourcePosition(iSoundSourceID, x, y, z);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceOrientationYPR, "Returns the orientation of a sound source (in yaw-pitch-roll angles)", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceOrientationYPR, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void getSoundSourceOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double yaw, pitch, roll;
    
    	pConnection->pCoreInterface->GetSoundSourceOrientationYPR(iSoundSourceID, yaw, pitch, roll);
    	plhs[0] = matlabCreateRealVector3(yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourceOrientationVU, "Returns the orientation of a sound source as view- and up-vector", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourceOrientationVU, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourceOrientationVU, view, "double-3", "View vector (length: 1)");
    DECLARE_FUNCTION_OUTARG(getSoundSourceOrientationVU, up, "double-3", "Up vector (length: 1)");
    
    void getSoundSourceOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double vx, vy, vz, ux, uy, uz;
    
    	pConnection->pCoreInterface->GetSoundSourceOrientationVU(iSoundSourceID, vx, vy, vz, ux, uy, uz);
    	plhs[0] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[1] = matlabCreateRealVector3(ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourcePositionOrientationYPR, "Returns the position and orientation (in yaw-pitch-roll angles) of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourcePositionOrientationYPR, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationYPR, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void getSoundSourcePositionOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, yaw, pitch, roll;
    
    	pConnection->pCoreInterface->GetSoundSourcePositionOrientationYPR(iSoundSourceID, x, y, z, yaw, pitch, roll);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourcePositionOrientationVU, "Returns the position and orientation (as view- and up-vector) of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourcePositionOrientationVU, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVU, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVU, view, "double-3", "View vector (length: 1)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVU, up, "double-3", "Up vector (length: 1)");
    
    
    void getSoundSourcePositionOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, vx, vy, vz, ux, uy, uz;
    
    	pConnection->pCoreInterface->GetSoundSourcePositionOrientationVU(iSoundSourceID, x, y, z, vx, vy, vz, ux, uy, uz);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[2] = matlabCreateRealVector3(ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourcePositionOrientationVelocityYPR, "Returns the position, orientation (in yaw-pitch-roll angles) and velocity of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourcePositionOrientationVelocityYPR, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityYPR, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityYPR, vel, "double-3", "Velocity vector [vx,vy,vz] (unit: meters/second)");
    
    void getSoundSourcePositionOrientationVelocityYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, yaw, pitch, roll, velX, velY, velZ;
    
    	pConnection->pCoreInterface->GetSoundSourcePositionOrientationVelocityYPR(iSoundSourceID, x, y, z, yaw, pitch, roll, velX, velY, velZ);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(yaw, pitch, roll);
    	plhs[2] = matlabCreateRealVector3(velX, velY, velZ);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSoundSourcePositionOrientationVelocityVU, "Returns the position, orientation (as view- and up-vector) and velocity of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getSoundSourcePositionOrientationVelocityVU, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityVU, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityVU, view, "double-3", "View vector (length: 1)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityVU, up, "double-3", "Up vector (length: 1)");
    DECLARE_FUNCTION_OUTARG(getSoundSourcePositionOrientationVelocityVU, vel, "double-3", "Velocity vector (vx, vy, vz) (unit: meters/second)");
    
    void getSoundSourcePositionOrientationVelocityVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, vx, vy, vz, ux, uy, uz, velX, velY, velZ;
    
    	pConnection->pCoreInterface->GetSoundSourcePositionOrientationVelocityVU(iSoundSourceID, x, y, z, vx, vy, vz, ux, uy, uz, velX, velY, velZ);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[2] = matlabCreateRealVector3(ux, uy, uz);
    	plhs[3] = matlabCreateRealVector3(velX, velY, velZ);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourcePosition, "Sets the position of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePosition, id, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePosition, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    
    void setSoundSourcePosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSourceID = matlabGetIntegerScalar(prhs[1], "id");
    	double x, y, z;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    
    	pConnection->pCoreInterface->SetSoundSourcePosition(iSourceID, x, y, z);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceOrientationYPR, "Sets the orientation of a sound source (in yaw-pitch-roll angles)", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceOrientationYPR, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void setSoundSourceOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double yaw, pitch, roll;
    	matlabGetRealVector3(prhs[2], "ypr", yaw, pitch, roll);
    
    	pConnection->pCoreInterface->SetSoundSourceOrientationYPR(iSoundSourceID, yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourceOrientationVU, "Sets the orientation of a sound source (as view- and up-vector)", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceOrientationVU, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourceOrientationVU, up, "double-3", "Up vector");
    
    void setSoundSourceOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double vx, vy, vz, ux, uy, uz;
    	matlabGetRealVector3(prhs[2], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[3], "up", ux, uy, uz);
    
    	pConnection->pCoreInterface->SetSoundSourceOrientationVU(iSoundSourceID, vx, vy, vz, ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourcePositionOrientationYPR, "Sets the position and orientation (in yaw, pitch, roll angles) of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationYPR, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationYPR, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void setSoundSourcePositionOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, yaw, pitch, roll;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "ypr", yaw, pitch, roll);
    
    	pConnection->pCoreInterface->SetSoundSourcePositionOrientationYPR(iSoundSourceID, x, y, z, yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourcePositionOrientationVU, "Sets the position and orientation (as view- and up vector) of a sound source", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVU, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVU, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVU, up, "double-3", "Up vector");
    
    void setSoundSourcePositionOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(5);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, vx, vy, vz, ux, uy, uz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[4], "up", ux, uy, uz);
    
    	pConnection->pCoreInterface->SetSoundSourcePositionOrientationVU(iSoundSourceID, x, y, z, vx, vy, vz, ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourcePositionOrientationVelocityYPR, "Sets the position, orientation (in yaw, pitch, roll angles) and velocity of a sound source", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityYPR, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityYPR, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityYPR, velocity, "double-3", "Velocity vector (unit: meters/second)");
    
    void setSoundSourcePositionOrientationVelocityYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(5);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, yaw, pitch, roll, velx, vely, velz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "ypr", yaw, pitch, roll);
    	matlabGetRealVector3(prhs[4], "velocity", velx, vely, velz);
    
    	pConnection->pCoreInterface->SetSoundSourcePositionOrientationVelocityYPR(iSoundSourceID, x, y, z, yaw, pitch, roll, velx, vely, velz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setSoundSourcePositionOrientationVelocityVU, "Sets the position, orientation (as view- and up vector) and velocity of a sound source", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityVU, soundSourceID, "integer-1x1", "Sound source ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityVU, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityVU, up, "double-3", "Up vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setSoundSourcePositionOrientationVelocityVU, velocity, "double-3", "Velocity vector (unit: meters/second)");
    
    void setSoundSourcePositionOrientationVelocityVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(6);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iSoundSourceID = matlabGetIntegerScalar(prhs[1], "soundSourceID");
    	double x, y, z, vx, vy, vz, ux, uy, uz, velx, vely, velz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[4], "up", ux, uy, uz);
    	matlabGetRealVector3(prhs[5], "velocity", velx, vely, velz);
    
    	pConnection->pCoreInterface->SetSoundSourcePositionOrientationVelocityVU(iSoundSourceID, x, y, z, vx, vy, vz, ux, uy, uz, velx, vely, velz);
    }
    
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Listeners                                              | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(getListenerIDs, "Returns the IDs of all listeners in the scene", "");
    DECLARE_FUNCTION_OUTARG(getListenerIDs, ids, "integer-1xN", "Vector containing the IDs");
    
    void getListenerIDs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<int> v;
    	pConnection->pCoreInterface->GetListenerIDs(v);
    	plhs[0] = matlabCreateIDList(v);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(createListener, "Creates a listener", "");
    DECLARE_FUNCTION_OPTIONAL_INARG(createListener, name, "string", "Displayed name", "''");
    DECLARE_FUNCTION_OPTIONAL_INARG(createListener, auralizationMode, "string", "Auralization mode", "'default'");
    DECLARE_FUNCTION_OPTIONAL_INARG(createListener, hrirID, "integer-1x1", "HRIR dataset ID", "-1");
    DECLARE_FUNCTION_OUTARG(createListener, id, "integer-1x1", "Sound source ID");
    
    void createListener(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sName = matlabGetString(prhs[1], "name");
    	std::string sAuralizationMode = matlabGetString(prhs[2], "auralizationMode");
    	int iAuralizationMode = IVACore::ParseAuralizationModeStr(sAuralizationMode);
    	int iHRIRID = matlabGetIntegerScalar(prhs[3], "hrirID");
    
    	int iListenerID = pConnection->pCoreInterface->CreateListener(sName, iAuralizationMode, iHRIRID);
    
    	plhs[0] = matlabCreateID(iListenerID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(deleteListener, "Deletes a listener from the scene", "Note: The active listener cannot be deleted!");
    DECLARE_FUNCTION_REQUIRED_INARG(deleteListener, listenerID, "integer-1x1", "Listener ID");
    
    void deleteListener(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	pConnection->pCoreInterface->DeleteListener(iListenerID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerName, "Returns name of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerName, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerName, name, "string", "Displayed name");
    
    void getListenerName(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    
    	std::string sName = pConnection->pCoreInterface->GetListenerName(iListenerID);
    	plhs[0] = mxCreateString(sName.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerName, "Sets the name of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerName, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerName, name, "string", "Displayed name");
    
    void setListenerName(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	std::string sName = matlabGetString(prhs[2], "name");
    
    	pConnection->pCoreInterface->SetListenerName(iListenerID, sName);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerAuralizationMode, "Returns the auralization mode of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerAuralizationMode, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerAuralizationMode, auralizationMode, "string", "Auralization mode");
    
    void getListenerAuralizationMode(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<int> v;
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    
    	int iAuralizationMode = pConnection->pCoreInterface->GetListenerAuralizationMode(iListenerID);
    	plhs[0] = mxCreateString( IVACore::GetAuralizationModeStr(iAuralizationMode, true).c_str() );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerAuralizationMode, "Sets the auralization mode of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerAuralizationMode, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerAuralizationMode, auralizationMode, "string", "Auralization mode");
    
    void setListenerAuralizationMode(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	std::string sAuralizationMode = matlabGetString(prhs[2], "auralizationMode");
    
    	// Get the current auralization mode first for computing relative modes (+|-)
    	int iCurAuralizationMode = pConnection->pCoreInterface->GetListenerAuralizationMode(iListenerID);
    	int iNewAuralizationMode = IVACore::ParseAuralizationModeStr(sAuralizationMode, iCurAuralizationMode);
    
    	pConnection->pCoreInterface->SetListenerAuralizationMode(iListenerID, iNewAuralizationMode);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( getListenerParameters, "Returns the current listener parameters", "");
    DECLARE_FUNCTION_REQUIRED_INARG( getListenerParameters, ID, "integer-1x1", "Listener identifier");
    DECLARE_FUNCTION_REQUIRED_INARG( getListenerParameters, args, "mstruct", "Requested parameters");
    DECLARE_FUNCTION_OUTARG( getListenerParameters, params, "mstruct", "Parameters");
    void getListenerParameters( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    	
    	int iID = matlabGetIntegerScalar( prhs[1], "ID" );
    	CVAStruct oArgs = matlabGetStruct( prhs[2], "args" );
    	CVAStruct oRet = pConnection->pCoreInterface->GetListenerParameters( iID, oArgs );
    	plhs[0] = matlabCreateStruct( oRet );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( setListenerParameters, "Sets listener parameters", "");
    DECLARE_FUNCTION_REQUIRED_INARG( setListenerParameters, ID, "integer-1x1", "Listener identifier");
    DECLARE_FUNCTION_REQUIRED_INARG( setListenerParameters, params, "mstruct", "Parameters");
    void setListenerParameters( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iID = matlabGetIntegerScalar( prhs[1], "ID" );
    	CVAStruct oParams = matlabGetStruct( prhs[2], "params" );
    	pConnection->pCoreInterface->SetListenerParameters( iID, oParams );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerHRIRDataset, "Returns for a listener the assigned HRIR dataset", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerHRIRDataset, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerHRIRDataset, hrirID, "integer-1x1", "HRIR dataset ID");
    
    void getListenerHRIRDataset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	int iHRIRID = pConnection->pCoreInterface->GetListenerHRIRDataset(iListenerID);
    	plhs[0] = matlabCreateID(iHRIRID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerHRIRDataset, "Set the HRIR dataset of a listener", "Note: In order to set no HRIR dataset, you can pass -1 to the method. In this case the listener will be silent.");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerHRIRDataset, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerHRIRDataset, hrirID, "integer-1x1", "HRIR dataset ID");
    
    void setListenerHRIRDataset(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	int iHRIRID = matlabGetIntegerScalar(prhs[2], "hrirID");
    
    	pConnection->pCoreInterface->SetListenerHRIRDataset(iListenerID, iHRIRID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerPosition, "Returns the position of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerPosition, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerPosition, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    
    void getListenerPosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z;
    	pConnection->pCoreInterface->GetListenerPosition(iListenerID, x, y, z);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerOrientationYPR, "Returns the orientation of a listener (in yaw-pitch-roll angles)", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerOrientationYPR, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void getListenerOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double yaw, pitch, roll;
    
    	pConnection->pCoreInterface->GetListenerOrientationYPR(iListenerID, yaw, pitch, roll);
    	plhs[0] = matlabCreateRealVector3(yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerOrientationVU, "Returns the orientation of a listener (as view- and up-vector)", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerOrientationVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_OUTARG(getListenerOrientationVU, up, "double-3", "Up vector");
    
    void getListenerOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double vx, vy, vz, ux, uy, uz;
    
    	pConnection->pCoreInterface->GetListenerOrientationVU(iListenerID, vx, vy, vz, ux, uy, uz);
    	plhs[0] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[1] = matlabCreateRealVector3(ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerPositionOrientationYPR, "Returns the position and orientation (in yaw-pitch-roll angles) of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerPositionOrientationYPR, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationYPR, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void getListenerPositionOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, yaw, pitch, roll;
    
    	pConnection->pCoreInterface->GetListenerPositionOrientationYPR(iListenerID, x, y, z, yaw, pitch, roll);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerPositionOrientationVU, "Returns the position and orientation (as view- and up-vector) of a listener", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerPositionOrientationVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVU, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVU, up, "double-3", "Up vector");
    
    
    void getListenerPositionOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, vx, vy, vz, ux, uy, uz;
    
    	pConnection->pCoreInterface->GetListenerPositionOrientationVU(iListenerID, x, y, z, vx, vy, vz, ux, uy, uz);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[2] = matlabCreateRealVector3(ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerPosition, "Sets the position of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPosition, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPosition, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    
    void setListenerPosition(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    
    	pConnection->pCoreInterface->SetListenerPosition(iListenerID, x, y, z);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerOrientationYPR, "Sets the orientation of a listener (in yaw-pitch-roll angles)", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerOrientationYPR, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void setListenerOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double yaw, pitch, roll;
    	matlabGetRealVector3(prhs[2], "ypr", yaw, pitch, roll);
    
    	pConnection->pCoreInterface->SetListenerOrientationYPR(iListenerID, yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerOrientationVU, "Sets the orientation of a listener (as view- and up-vector)", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerOrientationVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerOrientationVU, up, "double-3", "Up vector");
    
    void setListenerOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double vx, vy, vz, ux, uy, uz;
    	matlabGetRealVector3(prhs[2], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[3], "up", ux, uy, uz);
    
    	pConnection->pCoreInterface->SetListenerOrientationVU(iListenerID, vx, vy, vz, ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerPositionOrientationYPR, "Sets the position and orientation (in yaw-pitch-roll angles) of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationYPR, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationYPR, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    
    void setListenerPositionOrientationYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(4);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, yaw, pitch, roll;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "ypr", yaw, pitch, roll);
    
    	pConnection->pCoreInterface->SetListenerPositionOrientationYPR(iListenerID, x, y, z, yaw, pitch, roll);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerPositionOrientationVU, "Sets the position and orientation (as view- and up vector) of a listener", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVU, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVU, up, "double-3", "Up vector");
    
    void setListenerPositionOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(5);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, vx, vy, vz, ux, uy, uz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[4], "up", ux, uy, uz);
    
    	pConnection->pCoreInterface->SetListenerPositionOrientationVU(iListenerID, x, y, z, vx, vy, vz, ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerRealWorldHeadPositionOrientationVU, "Returns the real-world position and orientation (as view- and up vector) of the listener's head", "Note: The view and up vector must be an orthonormal pair of vectors. The parameter iListenerID has been added for future versions and is currently unsupported. You can set it any value you like.");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerRealWorldHeadPositionOrientationVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerRealWorldHeadPositionOrientationVU, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getListenerRealWorldHeadPositionOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_OUTARG(getListenerRealWorldHeadPositionOrientationVU, up, "double-3", "Up vector");
    
    void getListenerRealWorldHeadPositionOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, vx, vy, vz, ux, uy, uz;
    
    	pConnection->pCoreInterface->GetListenerRealWorldHeadPositionOrientationVU(iListenerID, x, y, z, vx, vy, vz, ux, uy, uz);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[2] = matlabCreateRealVector3(ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerRealWorldHeadPositionOrientationVU, "Updates the real-world position and orientation (as view- and up vector) of the listener's head", "Note: The view and up vector must be an orthonormal pair of vectors.");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerRealWorldHeadPositionOrientationVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerRealWorldHeadPositionOrientationVU, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerRealWorldHeadPositionOrientationVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerRealWorldHeadPositionOrientationVU, up, "double-3", "Up vector");
    
    void setListenerRealWorldHeadPositionOrientationVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(5);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, vx, vy, vz, ux, uy, uz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[4], "up", ux, uy, uz);
    
    	pConnection->pCoreInterface->SetListenerRealWorldHeadPositionOrientationVU(iListenerID, x, y, z, vx, vy, vz, ux, uy, uz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerPositionOrientationVelocityYPR, "Returns the position, orientation (in yaw-pitch-roll angles) and velocity of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerPositionOrientationVelocityYPR, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityYPR, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityYPR, velocity, "double-3", "velocity vector");
    
    void getListenerPositionOrientationVelocityYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, yaw, pitch, roll, velx, vely, velz;
    
    	pConnection->pCoreInterface->GetListenerPositionOrientationVelocityYPR(iListenerID, x, y, z, yaw, pitch, roll, velx, vely, velz);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(yaw, pitch, roll);
    	plhs[2] = matlabCreateRealVector3(velx, vely, velz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getListenerPositionOrientationVelocityVU, "Returns the position, orientation (as view- and up vector) and velocity of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getListenerPositionOrientationVelocityVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityVU, pos, "double-3", "Position vector [x,y,z] (unit: meters)");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityVU, view, "double-3", "View vector");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityVU, up, "double-3", "Up vector");
    DECLARE_FUNCTION_OUTARG(getListenerPositionOrientationVelocityVU, velocity, "double-3", "velocity vector");
    
    void getListenerPositionOrientationVelocityVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, vx, vy, vz, ux, uy, uz, velx, vely, velz;
    
    	pConnection->pCoreInterface->GetListenerPositionOrientationVelocityVU(iListenerID, x, y, z, vx, vy, vz, ux, uy, uz, velx, vely, velz);
    	plhs[0] = matlabCreateRealVector3(x, y, z);
    	plhs[1] = matlabCreateRealVector3(vx, vy, vz);
    	plhs[2] = matlabCreateRealVector3(ux, uy, uz);
    	plhs[3] = matlabCreateRealVector3(velx, vely, velz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerPositionOrientationVelocityYPR, "Sets the position, orientation (in yaw-pitch-roll angles) and velocity of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityYPR, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityYPR, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityYPR, ypr, "double-3", "Rotation angles [yaw, pitch, roll] (unit: degrees, not radians!)");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityYPR, velocity, "double-3", "velocity vector");
    
    void setListenerPositionOrientationVelocityYPR(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(5);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, yaw, pitch, roll, velx, vely, velz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "ypr", yaw, pitch, roll);
    	matlabGetRealVector3(prhs[4], "velocity", velx, vely, velz);
    
    	pConnection->pCoreInterface->SetListenerPositionOrientationVelocityYPR(iListenerID, x, y, z, yaw, pitch, roll, velx, vely, velz);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setListenerPositionOrientationVelocityVU, "Sets the position, orientation (as view- and up vector) and velocity of a listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityVU, listenerID, "integer-1x1", "Listener ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityVU, pos, "double-3", "Position vector [x, y, z] (unit: meters)");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityVU, view, "double-3", "view vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityVU, up, "double-3", "up vector");
    DECLARE_FUNCTION_REQUIRED_INARG(setListenerPositionOrientationVelocityVU, velocity, "double-3", "velocity vector");
    
    void setListenerPositionOrientationVelocityVU(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(6);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    	double x, y, z, vx, vy, vz, ux, uy, uz, velx, vely, velz;
    	matlabGetRealVector3(prhs[2], "pos", x, y, z);
    	matlabGetRealVector3(prhs[3], "view", vx, vy, vz);
    	matlabGetRealVector3(prhs[4], "up", ux, uy, uz);
    	matlabGetRealVector3(prhs[5], "velocity", velx, vely, velz);
    
    	pConnection->pCoreInterface->SetListenerPositionOrientationVelocityVU(iListenerID, x, y, z, vx, vy, vz, ux, uy, uz, velx, vely, velz);
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Scene                                                  | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(loadScene, "Loads a scene from a file (e.g. RAVEN project file)", "");
    DECLARE_FUNCTION_REQUIRED_INARG(loadScene, filename, "string", "Filename");
    
    void loadScene(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sFilename = matlabGetString(prhs[1], "filename");
    
    	pConnection->pCoreInterface->LoadScene(sFilename);
    
    	INFO("Scene '%s' successfully loaded\n", sFilename.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(isSceneLoaded, "Returns if a scene is loaded", "");
    DECLARE_FUNCTION_OUTARG(isSceneLoaded, result, "logical-1x1", "Is a scene loaded?");
    
    void isSceneLoaded(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	bool bResult = pConnection->pCoreInterface->IsSceneLoaded();
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getSceneInfo, "Returns information on the loaded scene", "");
    DECLARE_FUNCTION_OUTARG(getSceneInfo, info, "struct-1x1", "Information struct (name, filename, num polygons, etc.)");
    
    void getSceneInfo(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	CVASceneInfo si = pConnection->pCoreInterface->GetSceneInfo();
    	plhs[0] = matlabCreateSceneInfo(si);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getPortalIDs, "Return the IDs of all portal in the scene", "");
    DECLARE_FUNCTION_OUTARG(getPortalIDs, ids, "integer-1xN", "Vector containing the IDs");
    
    void getPortalIDs(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::vector<int> v;
    	pConnection->pCoreInterface->GetPortalIDs(v);
    	plhs[0] = matlabCreateIDList(v);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getPortalName, "Returns the name of a portal", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getPortalName, portalID, "integer-1x1", "Portal ID");
    DECLARE_FUNCTION_OUTARG(getPortalName, name, "string", "Displayed name");
    
    void getPortalName(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iPortalID = matlabGetIntegerScalar(prhs[1], "portalID");
    
    	std::string sName = pConnection->pCoreInterface->GetPortalName(iPortalID);
    	plhs[0] = mxCreateString(sName.c_str());
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setPortalName, "Sets the name of a portal", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setPortalName, portalID, "integer-1x1", "Portal ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setPortalName, name, "string", "Displayed name");
    
    void setPortalName(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iPortalID = matlabGetIntegerScalar(prhs[1], "portalID");
    	std::string sName = matlabGetString(prhs[2], "name");
    
    	pConnection->pCoreInterface->SetPortalName(iPortalID, sName);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getPortalState, "Returns the state of a portal", "");
    DECLARE_FUNCTION_REQUIRED_INARG(getPortalState, portalID, "integer-1x1", "Portal ID");
    DECLARE_FUNCTION_OUTARG(getPortalState, name, "double-1x1", "Portal state (range [0,1] where 0 => fully closed, 1 => fully opened)");
    
    void getPortalState(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iPortalID = matlabGetIntegerScalar(prhs[1], "portalID");
    
    	double dState = pConnection->pCoreInterface->GetPortalState(iPortalID);
    	plhs[0] = mxCreateDoubleScalar(dState);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setPortalState, "Sets the state of a portal", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setPortalState, portalID, "integer-1x1", "Portal ID");
    DECLARE_FUNCTION_REQUIRED_INARG(setPortalState, state, "double-1x1", "Portal state (range [0,1] where 0 => fully closed, 1 => fully opened)");
    
    void setPortalState(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(3);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iPortalID = matlabGetIntegerScalar(prhs[1], "portalID");
    	double dState = matlabGetIntegerScalar(prhs[2], "state");
    
    	pConnection->pCoreInterface->SetPortalState(iPortalID, dState);
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Global functions                                       | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION(getInputGain, "Returns the gain the audio device input channels", "");
    DECLARE_FUNCTION_OUTARG(getInputGain, gain, "double-1x1", "Input gain (amplification factor >=0)");
    
    void getInputGain(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double dGain = pConnection->pCoreInterface->GetInputGain();
    	plhs[0] = mxCreateDoubleScalar(dGain);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setInputGain, "Sets the gain the audio device input channels", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setInputGain, gain, "double-1x1", "Input gain (amplification factor >=0)");
    
    void setInputGain(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double dGain = matlabGetRealScalar(prhs[1], "gain");
    
    	pConnection->pCoreInterface->SetInputGain(dGain);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(isInputMuted, "Returns if the audio device inputs are muted", "");
    DECLARE_FUNCTION_OUTARG(isInputMuted, result, "logical-1x1", "Inputs muted?");
    
    void isInputMuted(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	bool bResult = pConnection->pCoreInterface->IsInputMuted();
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setInputMuted, "Sets the audio device inputs muted or unmuted", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setInputMuted, muted, "logical-1x1", "Muted?");
    
    void setInputMuted(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	bool bMuted = matlabGetBoolScalar(prhs[1], "muted");
    
    	pConnection->pCoreInterface->SetInputMuted(bMuted);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getOutputGain, "Returns the global output gain", "");
    DECLARE_FUNCTION_OUTARG(getOutputGain, gain, "double-1x1", "Output gain (amplification factor >=0)");
    
    void getOutputGain(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double dGain = pConnection->pCoreInterface->GetOutputGain();
    	plhs[0] = mxCreateDoubleScalar(dGain);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setOutputGain, "Sets global output gain", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setOutputGain, gain, "double-1x1", "Output gain (amplification factor >=0)");
    
    void setOutputGain(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double dGain = matlabGetRealScalar(prhs[1], "gain");
    
    	pConnection->pCoreInterface->SetOutputGain(dGain);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(isOutputMuted, "Returns if the global output is muted", "");
    DECLARE_FUNCTION_OUTARG(isOutputMuted, result, "logical-1x1", "Output muted?");
    
    void isOutputMuted(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	bool bResult = pConnection->pCoreInterface->IsOutputMuted();
    	plhs[0] = mxCreateLogicalScalar(bResult);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setOutputMuted, "Sets the global output muted or unmuted", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setOutputMuted, muted, "logical-1x1", "Output muted?");
    
    void setOutputMuted(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	bool bMuted = matlabGetBoolScalar(prhs[1], "muted");
    
    	pConnection->pCoreInterface->SetOutputMuted(bMuted);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getGlobalAuralizationMode, "Returns the global auralization mode", "");
    DECLARE_FUNCTION_OUTARG(getGlobalAuralizationMode, auralizationMode, "string", "Auralization mode");
    
    void getGlobalAuralizationMode(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iAuralizationMode = pConnection->pCoreInterface->GetGlobalAuralizationMode();
    	plhs[0] = mxCreateString( IVACore::GetAuralizationModeStr(iAuralizationMode, true).c_str() );
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setGlobalAuralizationMode, "Sets global auralization mode", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setGlobalAuralizationMode, auralizationMode, "string", "Auralization mode");
    
    void setGlobalAuralizationMode(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sAuralizationMode = matlabGetString(prhs[1], "auralizationMode");
    
    	// Get the current auralization mode first for computing relative modes (+|-)
    	int iCurAuralizationMode = pConnection->pCoreInterface->GetGlobalAuralizationMode();
    	int iNewAuralizationMode = IVACore::ParseAuralizationModeStr(sAuralizationMode, iCurAuralizationMode);
    
    	pConnection->pCoreInterface->SetGlobalAuralizationMode(iNewAuralizationMode);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getActiveListener, "Returns the active listener", "");
    DECLARE_FUNCTION_OUTARG(getActiveListener, listenerID, "integer-1x1", "Listener ID");
    
    void getActiveListener(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = pConnection->pCoreInterface->GetActiveListener();
    	plhs[0] = matlabCreateID(iListenerID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setActiveListener, "Sets the active listener", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setActiveListener, listenerID, "integer-1x1", "Listener ID");
    
    void setActiveListener(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	int iListenerID = matlabGetIntegerScalar(prhs[1], "listenerID");
    
    	pConnection->pCoreInterface->SetActiveListener(iListenerID);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(getCoreClock, "Returns the current core time", "");
    DECLARE_FUNCTION_OUTARG(getCoreClock, clk, "double-1x1", "Core clock time (unit: seconds)");
    
    void getCoreClock(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(1);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double dClk = pConnection->pCoreInterface->GetCoreClock();
    	plhs[0] = mxCreateDoubleScalar(dClk);
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setCoreClock, "Sets the core clock time", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setCoreClock, clk, "double-1x1", "New core clock time (unit: seconds)");
    
    void setCoreClock(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    	REQUIRE_INPUT_ARGS(2);
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	double dClk = matlabGetRealScalar(prhs[1], "clk");
    
    	pConnection->pCoreInterface->SetCoreClock(dClk);
    }
    
    // ------------------------------------------------------------
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Renderer & Reproduction                                | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    REGISTER_PUBLIC_FUNCTION( setReproductionModuleGain, "Sets the output gain of a reproduction module", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( setReproductionModuleGain, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_REQUIRED_INARG( setReproductionModuleGain, dGain, "double-1x1", "gain (factor)" );
    
    void setReproductionModuleGain( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	double dGain = matlabGetRealScalar( prhs[2], "dGain" );
    
    	pConnection->pCoreInterface->SetReproductionModuleGain( sID, dGain );
    }
    
    REGISTER_PUBLIC_FUNCTION( setReproductionModuleMuted, "Mutes a reproduction module", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( setReproductionModuleMuted, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_REQUIRED_INARG( setReproductionModuleMuted, bMuted, "logical-1x1", "Mute (true) or unmute (false)" );
    
    void setReproductionModuleMuted( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	bool bMuted = matlabGetBoolScalar( prhs[2], "bMuted" );
    
    	pConnection->pCoreInterface->SetReproductionModuleMuted( sID, bMuted );
    }
    
    REGISTER_PUBLIC_FUNCTION( isReproductionModuleMuted, "Is reproduction module muted?", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( isReproductionModuleMuted, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_OUTARG( isReproductionModuleMuted, bMuted, "logical-1x1", "true if muted, false if unmuted");
    
    void isReproductionModuleMuted( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	bool bMuted = pConnection->pCoreInterface->IsReproductionModuleMuted( sID );
    
    	plhs[0] = mxCreateLogicalScalar( bMuted );
    }
    
    REGISTER_PUBLIC_FUNCTION( getReproductionModuleGain, "Returns the reproduction module output gain", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( getReproductionModuleGain, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_OUTARG( getReproductionModuleGain, dGain, "double-1x1", "Gain (scalar)");
    
    void getReproductionModuleGain( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	double dGain = pConnection->pCoreInterface->GetReproductionModuleGain( sID );
    
    	plhs[0] = mxCreateDoubleScalar( dGain );
    }
    
    // Rendering
    
    REGISTER_PUBLIC_FUNCTION( setRenderingModuleGain, "Sets the output gain of a reproduction module", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( setRenderingModuleGain, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_REQUIRED_INARG( setRenderingModuleGain, dGain, "double-1x1", "gain (factor)" );
    
    void setRenderingModuleGain( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	double dGain = matlabGetRealScalar( prhs[2], "dGain" );
    
    	pConnection->pCoreInterface->SetRenderingModuleGain( sID, dGain );
    }
    
    REGISTER_PUBLIC_FUNCTION( setRenderingModuleMuted, "Mutes a reproduction module", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( setRenderingModuleMuted, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_REQUIRED_INARG( setRenderingModuleMuted, bMuted, "logical-1x1", "Mute (true) or unmute (false)" );
    
    void setRenderingModuleMuted( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 3 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	bool bMuted = matlabGetBoolScalar( prhs[2], "bMuted" );
    
    	pConnection->pCoreInterface->SetRenderingModuleMuted( sID, bMuted );
    }
    
    REGISTER_PUBLIC_FUNCTION( isRenderingModuleMuted, "Is reproduction module muted?", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( isRenderingModuleMuted, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_OUTARG( isRenderingModuleMuted, bMuted, "logical-1x1", "true if muted, false if unmuted");
    
    void isRenderingModuleMuted( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	bool bMuted = pConnection->pCoreInterface->IsRenderingModuleMuted( sID );
    
    	plhs[0] = mxCreateLogicalScalar( bMuted );
    }
    
    REGISTER_PUBLIC_FUNCTION( getRenderingModuleGain, "Get rendering module output gain", "" );
    DECLARE_FUNCTION_REQUIRED_INARG( getRenderingModuleGain, sModuleID, "string", "Module identifier" );
    DECLARE_FUNCTION_OUTARG( getRenderingModuleGain, dGain, "double-1x1", "Gain (scalar)");
    
    void getRenderingModuleGain( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS( 2 );
    
    	ConnectionHandle hHandle = GetConnectionHandle(prhs[0]);
    	CVAMatlabConnection* pConnection = g_vpConnections[hHandle];
    
    	std::string sID = matlabGetString( prhs[1], "sModuleID" );
    	double dGain = pConnection->pCoreInterface->GetRenderingModuleGain( sID );
    
    	plhs[0] = mxCreateDoubleScalar( dGain );
    }
    
    /* +----------------------------------------------------------+ *
     * |                                                          | *
     * |   Timer                                                  | *
     * |                                                          | *
     * +----------------------------------------------------------+ */
    
    // Timer momentan nur unter Windows verfgbar
    // TODO: Weitere Platform-Implementierungen
    #ifdef WIN32
    
    // Wchter, der automatisch das Kernel-Handle freigibt, wenn die DLL entladen wird
    class HandleGuard
    {
    public:
    	HANDLE hHandle;
    
    	inline HandleGuard()
    		: hHandle( 0 ) {};
    
    	inline ~HandleGuard()
    	{
    		Reset();
    	};
    
    	inline void Reset()
    	{
    		if( hHandle != 0 )
    		{
    			CloseHandle( hHandle );
    			hHandle = 0;
    		}
    	};
    };
    
    static HandleGuard g_oTimerHandle;
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION(setTimer, "Sets up the high-precision timer", "");
    DECLARE_FUNCTION_REQUIRED_INARG(setTimer, period, "double-1x1", "Timer period (unit: seconds)");
    
    void setTimer( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(2);
    
    	double dPeriod = matlabGetRealScalar( prhs[1], "period" );
    
    	if( dPeriod <= 0 )
    		VA_EXCEPT2(INVALID_PARAMETER, "Timer period must be greater zero");
    
    	if( g_oTimerHandle.hHandle == nullptr )
    	{
    		if( ( g_oTimerHandle.hHandle = CreateWaitableTimer( NULL, FALSE, NULL ) ) == nullptr )
    			VA_EXCEPT1("Failed to create timer");
    	}
    
    	LARGE_INTEGER liDueTime;
    	liDueTime.QuadPart=0;
    	long lPeriod = (long) std::floor(dPeriod * 1000); // Dauer in Millisekunden
    
    	if( SetWaitableTimer( g_oTimerHandle.hHandle, &liDueTime, lPeriod, NULL, NULL, FALSE ) == false )
    	{
    		g_oTimerHandle.Reset();
    		VA_EXCEPT1( "Failed to set waitable timer" );
    	}
    
    	// Execute an initial wait to force the next waitForTimer call from
    	// user space to be effective in any case. The initial wait seems
    	// to be skipped in eny (tested) case. This feels like a hack, though.
    	if( WaitForSingleObject( g_oTimerHandle.hHandle, INFINITE )  != WAIT_OBJECT_0 ) // ... yet no waiting here ...
    		VA_EXCEPT1( "Could not wait for waitable timer" );
    
    	return;
    }
    
    // ------------------------------------------------------------
    
    REGISTER_PUBLIC_FUNCTION( waitForTimer, "Wait for a signal of the high-precision timer", "" );
    void waitForTimer( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
    	REQUIRE_INPUT_ARGS(1);
    	
    	if( g_oTimerHandle.hHandle == 0 )
    		VA_EXCEPT1( "Timer not set" );
    
    	if( WaitForSingleObject( g_oTimerHandle.hHandle, INFINITE )  != WAIT_OBJECT_0 ) // This wait is effective.
    		VA_EXCEPT1( "Could not wait for waitable timer" );
    }
    
    #endif // WIN32