add: initial VAMatlab project

parents
%% Settings
deploy_dir = './';
src_dir = '../src';
vabase_include = '../../VABase/include';
vanet_include = '../../VANet/include';
vista_include = '../../Vista/VistaCoreLibs';
natnet_include = '../../ExternalLibs/NatNetSDK/NatNetSDK-2.7/include';
%% Compiler & project
% Determine the C++ compiler configuration
cxx = mex.getCompilerConfigurations( 'C++', 'Selected' );
if isempty( cxx )
error( 'No C++ compiler installed or selected for Matlab. Please run ''mex -setup''.' );
end
% Output file
outfile = fullfile( deploy_dir, [ 'VAMatlab.' mexext ] );
% Source files
source_files = { 'MatlabHelpers.cpp', 'VAMatlabConnection.cpp', 'VAMatlabExecutable.cpp', 'VAMatlabTracking.cpp' };
srcs = fullfile( src_dir, source_files );
srcs = sprintf( '%s ', srcs{:} );
%% Build
fprintf( 'Building VA Matlab executable\n\tCompiler: ''%s''\n\tOutput: ''%s''\n', cxx.Name, outfile )
% Create the destination directory if it does not exist
if ~exist( deploy_dir, 'dir' )
mkdir( deploy_dir );
end
% Note: We need to call mex via 'system' here, because we used the symbol
% 'mex' with '.' above and Matlab would complain when doing 'mex ...'
cmd = sprintf( 'mex -O -I%s -I%s -I%s -I%s %s -output %s', vabase_include, vanet_include, vista_include, natnet_include, ...
srcs, outfile );
% Debug: disp(cmd);
[ errorcode, result ] = system( cmd, '-echo' );
if errorcode ~= 0
error( 'Building VA Matlab executable failed' )
end
fprintf( 'VA Matlab executable successfully built to ''%s''\n', outfile )
classdef itaVA < handle
%ITAVA Remote interface for VA real-time auralization servers
%
% This class realizes a remote connection to a VA real-time
% auralization server and implements the full VA core interface
% in Matlab. This way you connect to an auralization server
% and control all of its features to perform a real-time
% auralization. In order to get understand to the concepts behind VA
% please refer to the VA documentation.
%
% Usage & examples:
%
% - Create an interface and connect to the server running on the
% same computer (localhost)
%
% va = itaVA('localhost');
%
% If no error occurs, you can then use the interface to work with
% the VA server. Best practice is to reset it first:
%
% va.reset
%
% Then you can call other methods. For instance create a sound
% source:
%
% sourceID = va.createSoundSource('Virtual sound source')
%
% When everything is done, do not forget to close the connection.
% You can call disconnect on the instance or simply clear it:
%
% clear va
%
% - You can find more examples in the demo files
%
% Questions? Contact the author: Frank.Wefers@akustik.rwth-aachen.de
%
% Otherwise => Enjoy!
%
properties(Hidden = true, Access = private)
handle = int32(0); % Connection handle
% Connection defaults
DEFAULT_SERVER_PORT = 12340;
end
methods(Static)
function [version] = getVersion()
% Return the version of the VA Matlab interface
%
% Parameters:
%
% None
%
% Return values:
%
% version [string] Version string
version = VAMatlab('getVersion');
end
function [] = setVerboseMode(mode)
% Sets the verbose level of the VA Matlab interface
%
% Parameters:
%
% mode [string] Verbose mode ('quiet'|'normal')
%
% Return values:
%
% None
%
% Remarks:
%
% - If you do not want any messages from the extension
% set the verbose mode to 'quiet'
%
VAMatlab('setVerboseMode', mode);
end
end
methods
function this = itaVA(addressstring)
% Initialization constructor. Initiiates a new connection.
%
% Parameters:
%
% addressstring [string] Hostname or IP address and port of the
% server string (name:port), optional
%
% Return values:
%
% None
%
% Remarks:
%
% - You can leave the argument 'address' undefined, in order
% to create an clear, unconnected instance and connect to
% a server later using the method 'connect'
% - Example: core = itaVA;
% core = itaVA('localhost:12340');
%
if (nargin > 0)
this.connect(addressstring)
end
end
function delete(this)
% Destructor. Automatically disconnects an existing connection.
this.disconnect
end
function [connected] = isConnected(this)
% Returns if a connection to a server is established
connected = VAMatlab('isConnected', this.handle);
end
function connect(this, addressstring)
% Connects to a server
%
% Parameters:
%
% addressstring [string] Hostname or IP address and port of the
% server string (name:port), optional
%
% Return values:
%
% None
%
% Remarks:
%
% - An error occurs if the instance is already connected
% - Example: core.connect('localhost:12340')
%
if this.handle~=0
error('Already connected. Close the existing connection first.');
end
if nargin == 2
if isempty(addressstring)
error('Server address must not be empty.');
end
else
addressstring = 'localhost';
end
this.handle = VAMatlab('connect', addressstring);
end
function disconnect(this)
% Disconnects from a server
VAMatlab('disconnect', this.handle)
this.handle = int32(0);
end
function [state] = getServerState(this)
% Returns the state of the connected server
%
% Use this function to check whether the server is
% running fine and does not have any problems.
%
% Parameters:
%
% None
%
% Return values:
%
% state [integer-1x1] Server stat
%
% States:
%
% - 0 = Connected, but server not configured. Failure.
% - 1 = Connected and ready for usage.
% - 2 = Connected, but server has failure.
%
if this.handle==0, error('Not connected.'); end;
state = VAMatlab('getServerState', this.handle);
end
function connectTracker( this, remote_ip, local_ip )
% Connects to a local NatNet tracking server
%
% The server will update a virtual listener for real-time
% sound synthesis and the real world listener position for
% those sound reproductions that need this information, like
% Crosstalk-Cancellation.
%
% See also setTrackedListener.
%
% Parameters (optional):
%
% remote_ip [char] Remote ip address
% local_ip [char] Local ip address
%
if( nargin == 1 )
remote_ip = '127.0.0.1';
local_ip = '127.0.0.1';
end
VAMatlab( 'ConnectTracker', this.handle, remote_ip, local_ip );
end
function [connected] = isTrackerConnected( this )
% Returns true, if tracker is connected
connected = VAMatlab( 'IsTrackerConnected', this.handle );
end
function setTrackedListener( this, listener_id )
% Connects a VA listener with the tracked rigid body
%
% Parameters:
%
% listener_id [integer-1x1] VA listener id
%
VAMatlab( 'SetTrackedListener', this.handle, listener_id );
end
function setTrackedSource( this, source_id )
% Connects a VA source with the tracked rigid body
%
% Parameters:
%
% source_id [integer-1x1] VA listener id
%
VAMatlab( 'SetTrackedSource', this.handle, source_id );
end
function disconnectTracker( this )
% Disconnects from the NatNet tracking server
VAMatlab( 'DisconnectTracker', this.handle )
end
function setRigidBodyIndex( this, index )
% Sets the index of the rigid body to be tracked (default is 1)
VAMatlab( 'SetRigidBodyIndex', this.handle, index )
end
function setRigidBodyTranslation( this, translation )
% Sets the pivot point translation for the tracked rigid body
%
% Parameters:
%
% translation [double-3x1] Translation in local coordinate system of rigid body [m]
%
VAMatlab( 'SetRigidBodyTranslation', this.handle, translation )
end
function setRigidBodyRotation( this, rotation )
% Sets the rotation of orientation for the tracked rigid body
%
% Given rotation has to be a Matlab quaternion type (order: w(real), i, j, k)
%
% Parameters:
%
% rotation [quaternion] Rotation of rigid body
%
VAMatlab( 'SetRigidBodyRotation', this.handle, rotation )
end
%% --= Functions =--
###STUBCODE###
function display(this)
% TODO: Define nice behaviour
% if this.handle
% fprintf('Connection established to server ''%s''\n', this.getServerAddress())
% else
% fprintf('Not connected\n');
% end
end
end
end
%
% Code generator for the VA Matlab interface facade class
%
% Desc: This script generates the code for the Matlab
% facade class to the VAInterface MEXExtension.
% It takes the class template code and inserts
% all stubs for the functions in the VAConnector
% interface. These are derived using the reflexion
% mechanism ('enumerateFunctions')
%
% Author: Frank Wefers (fwefers@akustik.rwth-aachen.de)
% Version: $Id: $
%
% Clear everything first, so that no inconsistens
% class instances can exist (we have to use
clear all;
% Uncomment the path you are building your matlab executable against. It is
% sufficient to execute this once for a matlab session. It is always recommended
% to build against a release executable, use debug mode only if you actually
% want to debug the mex library. There is a 3rdParty/Matlab if you want to
% link the executable against a Matlab version/platform that is not installed
% on your machine.
script_dir = '../../VABuild/dist/win32-x64/matlab'
deploy_dir = '../../VABuild/dist/win32-x64/matlab/win64'
% Add to MATLABPATH temporarily
addpath( script_dir )
addpath( deploy_dir )
% Parameters
templateFile = 'itaVA.proto.m';
outputFile = fullfile( script_dir, 'itaVA.m' );
fprintf( 'Generating code for itaVA Matlab class ''%s'' ...\n', outputFile );
code = fileread( templateFile );
stubCode = generateStubs();
code = strrep( code, '###STUBCODE###', stubCode );
% Write the results
fid = fopen( outputFile, 'w' );
fprintf( fid, '%s', code );
fclose( fid );
fprintf('Matlab class ''%s'' successfully built\n', outputFile);
% Remove from MATLABPATH (otherwise naming conflicts may occur with
% ITA-Toolbox/applications/VA/*)
rmpath( script_dir )
rmpath( deploy_dir )
%this debug script is for debugging the VA-to-Matlab connection
% without the use of the facade class "itaVA"
% To use MSVS for debugging the MEX library, in VS select "Debugging >
% Append to process" ... then select the MATLAB.exe process and start to
% execute commands in Matlab that are calling functions of the MEX file
cd 'D:\Users\stienen\VA\VAMatlab\Matlab'
addpath( '../../VABuild/Build/Debug_x64' )
addpath( '../../VistaCoreLibs/lib/x64' )
addpath( '../../3rdParty/NatNetSDK/lib/x64' )
conn = VAMatlabD( 'connect', 'localhost:12340' );
L = VAMatlabD( 'createListener', conn, 'itaVA_Tracked_Listener', 'default', -1 );
VAMatlabD( 'SetTrackedListener', conn,L )
%VAMatlabD( 'SetTrackedSource', conn,L )
VAMatlabD( 'SetRigidBodyIndex', conn, 1 )
VAMatlabD( 'SetRigidBodyTranslation', conn, [ 0 0 3 ] )
q = ita_quaternion( [ pi/sqrt(2) 0 1/sqrt(2) 0 ] )
q = q.normalize
VAMatlabD( 'SetRigidBodyRotation', conn, q.e(:)' )
VAMatlabD( 'connectTracker', conn )
b = VAMatlabD( 'IsTrackerConnected', conn )
VAMatlabD( 'disconnectTracker', conn )
%VAMatlabD( 'connectTracker', conn, '137.226.61.85', '137.226.61.85' )
modinfos = VAMatlabD( 'enumerateModules', conn );
istruct = struct;
istruct.info = '';
ostruct = VAMatlabD( 'callModule', conn, 'GenericPath:MyGenericRenderer', istruct )
istruct = struct();
istruct.command = 'UPDATE';
istruct.ListenerID = 1;
istruct.SourceID = 1;
if false
istruct.type = 'FilePath';
istruct.FilePath = '$(VADataDir)/HPEQ/HD600_all_eq_128_stereo.wav';
end
if true
istruct.type = 'DATA';
istruct.IRDataCh1 = [ 0.9 zeros( 1, 2048 ) ];
istruct.IRDataCh2 = [ 0.1 zeros( 1, 2048 ) ];
end
if false
sweep = ita_time_crop( ita_generate_sweep, [1 1350], 'samples' ) * 0.03;
istruct.type = class( sweep );
istruct.itaAudio = ita_merge( sweep, sweep );
end
ostruct = VAMatlabD( 'callModule', conn, 'GenericPath:MyGenericRenderer', istruct );
%VAMatlabD( 'callModule', conn, 'hprep', { 'print', 'help' } ) % will print on std::cout @ real VACore, i.e. VAGUI or Console
%lhs_arg = VAMatlabD( 'callModule', conn, 'hprep', { 'get', 'gain' } )
%VAMatlabD( 'callModule', conn, 'hprep', { 'set', 'gain', 'value', lhs_arg / 3 } )
%lhs_arg_new = VAMatlabD( 'callModule', conn, 'hprep', { 'get', 'gain' } )
VAMatlabD( 'disconnect', conn )
clear VAMatlabD % release to allow write access for msvc
%% itaVA simple example code
% Create itaVA
va = itaVA;
% Connect to VA application (start the application first)
va.connect( 'localhost' )
% Reset VA to clear the scene
va.reset()
% Control output gain
va.setOutputGain( .25 )
% Add the current absolute folder path to VA application
va.addSearchPath( pwd );
% Create a signal source and start playback
ita_write_wav( ita_demosound, 'ita_demosound.wav', 'overwrite' );
X = va.createAudiofileSignalSource( 'ita_demosound.wav' );
va.setAudiofileSignalSourcePlaybackAction( X, 'play' )
va.setAudiofileSignalSourceIsLooping( X, true );
% Create a virtual sound source and set a position
S = va.createSoundSource( 'itaVA_Source' );
va.setSoundSourcePosition( S, [0 1.7 -2] )
% Connect the signal source to the virtual sound source
va.setSoundSourceSignalSource( S, X )
% Create a listener with a HRTF and position him
H = va.loadHRIRDataset( '$(DefaultHRIR)' );
L = va.createListener( 'itaVA_Listener', 'default', H );
va.setListenerPosition( L, [0 1.7 0] )
va.setListenerOrientationYPR( L, [0 0 0] ) % Default view is to -Z (OpenGL)
% Set the listener as the active one
va.setActiveListener( L )
% Now close connection
va.disconnect()
% VA virtual scene is still active now ...
% Explore itaVA class ...
doc itaVA
%% itaVA tracked listener example code
% This assumes you already have set up a virtual scene without listener
% Create itaVA and connect
va = itaVA( 'localhost' )
% Create a listener
L = va.createListener( 'itaVA_Tracked_Listener' );
% OptiTrack tracker conneection and listener updates
va.setTrackedListener( L )
va.connectTracker
pause( 12 ) % Observe how you can move the virtual listener in VAGUI
va.disconnectTracker
% Remove listener again
va.deleteListener( L )
% Now close connection
va.disconnect()
% Stub generator for the VA Matlab facade class
% Author: Frank Wefers (fwefers@akustik.rwth-aachen.de)
function [output] = generateStubs()
% Get interface describtion
d = VAMatlab('enumerateFunctions');
code = '';
for i=1:length(d)
% Concatenate the input and output argument lists
inargs = '';
ninargs = length(d(i).inargs);
for j=1:ninargs
if (j>1) inargs = strcat(inargs, ', '); end
inargs = strcat(inargs, sprintf('%s', d(i).inargs(j).name));
end
outargs = '';
noutargs = length(d(i).outargs);
for j=1:noutargs
if (j>1) outargs = strcat(outargs, ', '); end
outargs = strcat(outargs, sprintf('%s', d(i).outargs(j).name));
end
if ninargs > 0
code = [code sprintf('\tfunction [%s] = %s(this, %s)\n', outargs, d(i).name, inargs)];
else
code = [code sprintf('\tfunction [%s] = %s(this)\n', outargs, d(i).name)];
end
code = [code sprintf('\t\t%% %s\n', d(i).desc)];
% Argument and return value documentation
code = [code sprintf('\t\t%%\n\t\t%% Parameters:\n\t\t%%\n')];
if (ninargs == 0)
code = [code sprintf('\t\t%% \tNone\n')];
else
for j=1:ninargs
if (d(i).inargs(j).optional)
code = [code sprintf('\t\t%% \t%s [%s] %s (optional, default: %s)\n', ...
d(i).inargs(j).name, ...
d(i).inargs(j).type, ...
d(i).inargs(j).desc, ...
d(i).inargs(j).default)];
else
code = [code sprintf('\t\t%% \t%s [%s] %s\n', ...
d(i).inargs(j).name, ...
d(i).inargs(j).type, ...
d(i).inargs(j).desc)];
end
end
end
code = [code sprintf('\t\t%%\n\t\t%% Return values:\n\t\t%%\n')];
if (noutargs == 0)
code = [code sprintf('\t\t%% \tNone\n')];
else
for j=1:noutargs
code = [code sprintf('\t\t%% \t%s [%s] %s\n', ...
d(i).outargs(j).name, ...
d(i).outargs(j).type, ...
d(i).outargs(j).desc)];
end
end
code = [code sprintf('\t\t%%\n\n')];
% Matlab code that checks that a connection is established
code = [code sprintf('\t\tif this.handle==0, error(''Not connected.''); end;\n\n')];
% Matlab code for default values in optional input parameters
for j=1:ninargs
if (d(i).inargs(j).optional)
code = [code sprintf('\t\tif ~exist(''%s'',''var''), %s = %s; end\n', ...
d(i).inargs(j).name, d(i).inargs(j).name, d(i).inargs(j).default)];
end
end
% Matlab code calling the MEX
if (noutargs > 0)
if (ninargs > 0)
code = [code sprintf('\t\t[%s] = VAMatlab(''%s'', this.handle, %s);\n', outargs, d(i).name, inargs)];
else
code = [code sprintf('\t\t[%s] = VAMatlab(''%s'', this.handle);\n', outargs, d(i).name)];
end
else
if (ninargs > 0)
code = [code sprintf('\t\tVAMatlab(''%s'', this.handle, %s);\n', d(i).name, inargs)];
else
code = [code sprintf('\t\tVAMatlab(''%s'', this.handle);\n', d(i).name)];
end
end
code = [code sprintf('\tend\n\n')];
end
output = code;
end
\ No newline at end of file
/*
*
* 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: FunctionMappings.h
*
* Purpose: Reflexion mechanisms for the Matlab extension functions
*
* Authors: Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*/
// $Id: $
#ifndef __FUNCTIONMAPPINGS_H__
#define __FUNCTIONMAPPINGS_H__
#include <assert.h>
#include <algorithm>
#include <map>
#include <string>