vasingletonmethods.hpp 29.5 KB
Newer Older
1 2 3
#include <Python.h>
#include <VANetClient.h>
#include <VACore.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
4
#include <VAStruct.h>
5 6 7
#include <VAException.h>
#include <string.h>

8
// If you want to extend the va Python pSelf interface, also add
9 10 11 12
// the function to the va_methods table in vasingleton.cpp - otherwise they will not show up.
// Documentation goes into vasingletondoc.hpp

static IVANetClient* g_pVANetClient = nullptr; //!< Static pointer to VANetClient instance
13
static PyObject* g_pVAError = nullptr; //!< Static pointer to error instance
14

15 16 17 18
// Ugly definitions to ease try-catching VA exceptions
#define VAPY_REQUIRE_CONN_TRY try { RequireCoreAvailable();
#define VAPY_CATCH_RETURN } catch (const CVAException& oError) { PyErr_SetString(PyExc_Exception, oError.ToString().c_str()); return NULL; }

19
//! Helper for API dev
20
static PyObject* va_not_implemented( PyObject*, PyObject* )
21 22
{
	VA_EXCEPT_NOT_IMPLEMENTED;
23
};
24

25 26 27
//! Raises an exception if core is not available
static void RequireCoreAvailable()
{
28 29
	if( !g_pVANetClient )
		VA_EXCEPT2( CVAException::NETWORK_ERROR, "VA client not available, please connect first" );
30

31 32 33 34 35 36 37 38 39 40 41 42 43
	if( !g_pVANetClient->GetCoreInstance() )
		VA_EXCEPT2( CVAException::NETWORK_ERROR, "VA client available, but access to VA interface failed. Please reconnect." );
};

std::string SaveStringToUnicodeConversion( const std::string& sInputString )
{
	std::string sOutputString = sInputString;
	const Py_ssize_t iLength = sInputString.length();
	char* pcBuffer( &sOutputString[ 0 ] );
	for( Py_ssize_t i = 0; i < iLength; i++ )
		if( pcBuffer[ i ] < 0 )
			pcBuffer[ i ] = '_';
	return &sOutputString[ 0 ];
44
};
45

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
46
//! Helper to convert recursively from VAStruct to Python dict
47
PyObject* ConvertVAStructToPythonDict( const CVAStruct& oInStruct )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
48
{
49 50 51
	PyObject* pOutDict = PyDict_New();

	CVAStruct::const_iterator cit = oInStruct.Begin();
52
	while( cit != oInStruct.End() )
53
	{
54 55
		const std::string sKey( ( *cit++ ).first );
		const CVAStructValue& oValue( oInStruct[ sKey ] );
56 57

		PyObject* pNewValue = nullptr;
58
		if( oValue.IsBool() )
59
		{
60
			pNewValue = PyBool_FromLong( bool( oValue ) );
61
		}
62
		else if( oValue.IsInt() )
63
		{
64
			pNewValue = PyLong_FromLong( int( oValue ) );
65
		}
66
		else if( oValue.IsDouble() )
67
		{
68
			pNewValue = PyFloat_FromDouble( double( oValue ) );
69
		}
70
		else if( oValue.IsString() )
71
		{
72
			pNewValue = PyUnicode_FromString( SaveStringToUnicodeConversion( std::string( oValue ) ).c_str() );
73
		}
74
		else if( oValue.IsStruct() )
75
		{
76
			pNewValue = ConvertVAStructToPythonDict( oValue );
77
		}
78
		else if( oValue.IsData() )
79 80 81
		{
			VA_EXCEPT_NOT_IMPLEMENTED;
		}
82
		else if( oValue.IsSampleBuffer() )
83 84 85 86 87
		{
			VA_EXCEPT_NOT_IMPLEMENTED;
		}
		else
		{
88
			VA_EXCEPT2( INVALID_PARAMETER, "Could not interpret value of key '" + sKey + "' as a supported python dict type. Value was" + oValue.ToString() );
89 90
		}

91 92
		if( !pNewValue )
			VA_EXCEPT2( INVALID_PARAMETER, "Could not create python object from value of key '" + sKey + "'. Value was" + oValue.ToString() );
93

94 95
		if( PyDict_SetItemString( pOutDict, sKey.c_str(), pNewValue ) == -1 )
			VA_EXCEPT2( INVALID_PARAMETER, "Could not create python object from value of key '" + sKey + "'. Value was" + oValue.ToString() );
96 97 98
	}

	return pOutDict;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
99 100 101
};

//! Helper to convert recursively from Python dict to VAStruct
102
CVAStruct ConvertPythonDictToVAStruct( PyObject* pInDict )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
103
{
104 105
	CVAStruct oReturn;

106 107
	PyObject* pKeyList = PyDict_Keys( pInDict );
	PyObject* pValueList = PyDict_Values( pInDict );
108

109
	for( Py_ssize_t i = 0; i < PyList_Size( pKeyList ); i++ )
110
	{
111 112
		PyObject* pKey = PyList_GetItem( pKeyList, i );
		PyObject* pValue = PyList_GetItem( pValueList, i );
113
		char* pcKeyName = nullptr;
114 115
		if( !PyArg_Parse( pKey, "s", &pcKeyName ) )
			VA_EXCEPT2( CVAException::INVALID_PARAMETER, "Invalid key '" + std::string( pcKeyName ) + "'" );
116

117
		if( Py_None == pValue )
118
		{
119
			oReturn[ pcKeyName ] = false;
120
		}
121
		else if( PyBool_Check( pValue ) )
122
		{
123
			oReturn[ pcKeyName ] = ( PyLong_AsLong( pValue ) != 0 );
124
		}
125
		else if( PyLong_Check( pValue ) )
126
		{
127
			oReturn[ pcKeyName ] = PyLong_AsLong( pValue );
128
		}
129
		else if( PyFloat_Check( pValue ) )
130
		{
131
			oReturn[ pcKeyName ] = PyFloat_AsDouble( pValue );
132
		}
133
		else if( PyUnicode_Check( pValue ) )
134 135
		{
			char* pcStringValue = nullptr;
136 137 138
			if( !PyArg_Parse( pValue, "s", &pcStringValue ) )
				VA_EXCEPT2( CVAException::INVALID_PARAMETER, "Invalid string value at key '" + std::string( pcKeyName ) + "': " + std::string( pcStringValue ) );
			oReturn[ pcKeyName ] = std::string( pcStringValue );
139
		}
140
		else if( PyDict_Check( pValue ) )
141
		{
142
			oReturn[ pcKeyName ] = ConvertPythonDictToVAStruct( pValue );
143
		}
144
		else if( PyList_Check( pValue ) )
145 146 147 148
		{
			// Sample buffer
			VA_EXCEPT_NOT_IMPLEMENTED;
		}
149
		else if( PyByteArray_Check( pValue ) )
150 151 152 153 154 155
		{
			// Data blob
			VA_EXCEPT_NOT_IMPLEMENTED;
		}
		else
		{
156
			VA_EXCEPT2( INVALID_PARAMETER, "Could not interpret value of key '" + std::string( pcKeyName ) + "' as a supported VAStruct type." )
157 158 159 160
		}
	}

	return oReturn;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
161 162 163 164 165
};


// ------------------------------- Python module extension methods

166
static PyObject* va_connect( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
167
{
168
	if( !g_pVANetClient )
169 170
		g_pVANetClient = IVANetClient::Create();

171
	if( g_pVANetClient->IsConnected() )
172
	{
173
		PyErr_WarnEx( NULL, "Was still connected, forced disconnect.", 1 );
174
		g_pVANetClient->Disconnect();
175 176 177
	}

	static const char * const _keywords[] = { "server", "port", NULL };
178
	static _PyArg_Parser _parser = { "|si:connect", _keywords, 0 };
179
	char* pcServerIP = nullptr;
180 181
	int iServerPort = 12340;

182
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcServerIP, &iServerPort ) )
183
		return NULL;
184

185
	std::string sServerIP = pcServerIP ? std::string( pcServerIP ) : "localhost";
186

187 188
	if( IVANetClient::VA_NO_ERROR == g_pVANetClient->Initialize( sServerIP, iServerPort ) )
		return PyBool_FromLong( 1 );
189

190
	PyErr_SetString( PyExc_ConnectionError, std::string( "Could not connect to " + sServerIP + " on " + std::to_string( ( long ) iServerPort ) ).c_str() );
191
	return NULL;
192
};
193

194
static PyObject* va_disconnect( PyObject*, PyObject* )
195
{
196 197
	if( !g_pVANetClient )
		return PyBool_FromLong( 0 );
198

199
	return PyBool_FromLong( g_pVANetClient->Disconnect() );
200
};
201

202
static PyObject* va_is_connected( PyObject*, PyObject* )
203
{
204 205
	if( !g_pVANetClient )
		return PyBool_FromLong( 0 );
206
	else
207
		return PyBool_FromLong( g_pVANetClient->IsConnected() );
208
};
209

210
static PyObject* va_reset( PyObject*, PyObject* )
211
{
212
	VAPY_REQUIRE_CONN_TRY;
213
	g_pVANetClient->GetCoreInstance()->Reset();
214
	Py_INCREF( Py_None );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
215
	return Py_None;
216 217
	VAPY_CATCH_RETURN;
};
218

219
static PyObject* va_enumerate_modules( PyObject*, PyObject* )
220
{
221
	VAPY_REQUIRE_CONN_TRY;
222 223

	std::vector< CVAModuleInfo > voModuleInfos;
224
	g_pVANetClient->GetCoreInstance()->EnumerateModules( voModuleInfos );
225

226
	PyObject* pModuleList = PyList_New( voModuleInfos.size() );
227

228
	for( size_t i = 0; i < voModuleInfos.size(); i++ )
229
	{
230 231 232
		CVAModuleInfo& oModule( voModuleInfos[ i ] );
		PyObject* pModuleInfo = Py_BuildValue( "{s:i,s:s,s:s}", "index", i, "name", oModule.sName.c_str(), "description", oModule.sDesc.c_str() );
		PyList_SetItem( pModuleList, i, pModuleInfo ); // steals reference
233 234 235 236
	}

	return pModuleList;

237 238 239
	VAPY_CATCH_RETURN;
};

240
static PyObject* va_call_module( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
241
{
242
	VAPY_REQUIRE_CONN_TRY;
243

244 245
	static const char * const _keywords[] = { "module_name", "arguments_dict", NULL };
	static _PyArg_Parser _parser = { "sO!:call_module", _keywords, 0 };
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
246
	char* pcModuleName = nullptr;
247
	PyObject* pArgumentsDict = nullptr;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
248

249
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcModuleName, &PyDict_Type, &pArgumentsDict ) )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
250
		return NULL;
251

252 253
	std::string sModuleName = std::string( pcModuleName );
	CVAStruct oInArgs = ConvertPythonDictToVAStruct( pArgumentsDict );
254
	CVAStruct oOutArgs;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
255

256
	g_pVANetClient->GetCoreInstance()->CallModule( sModuleName, oInArgs, oOutArgs );
257

258
	return ConvertVAStructToPythonDict( oOutArgs );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
259

260 261 262
	VAPY_CATCH_RETURN;
};

263
static PyObject* va_add_search_path( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
264
{
265
	VAPY_REQUIRE_CONN_TRY;
266

267 268 269
	static const char * const _keywords[] = { "directory_path", NULL };
	static _PyArg_Parser _parser = { "s:add_search_path", _keywords, 0 };
	char* pcPath = nullptr;
270
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcPath ) )
271 272
		return NULL;

273
	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->AddSearchPath( std::string( pcPath ) ) );
274

275 276 277
	VAPY_CATCH_RETURN;
};

278 279

static PyObject* va_create_listener( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
280
{
281
	VAPY_REQUIRE_CONN_TRY;
282

283 284 285 286 287
	static const char * const _keywords[] = { "name", NULL };
	static _PyArg_Parser _parser = { "s:create_listener", _keywords, 0 };
	char* pcName = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcName ) )
		return NULL;
288

289 290
	std::string sName = pcName ? std::string( pcName ) : "PyListener";
	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->CreateListener( sName, IVACore::VA_AURAMODE_ALL ) );
291

292 293
	VAPY_CATCH_RETURN;
};
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
294

295
static PyObject* va_is_scene_locked( PyObject*, PyObject* )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
296
{
297
	VAPY_REQUIRE_CONN_TRY;
298
	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->IsSceneLocked() );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
299 300 301
	VAPY_CATCH_RETURN;
};

302
static PyObject* va_lock_scene( PyObject*, PyObject* )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
303
{
304
	VAPY_REQUIRE_CONN_TRY;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
305
	g_pVANetClient->GetCoreInstance()->LockScene();
306
	Py_INCREF( Py_None );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
307
	return Py_None;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
308 309 310
	VAPY_CATCH_RETURN;
};

311
static PyObject* va_unlock_scene( PyObject*, PyObject* )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
312 313
{
	VAPY_REQUIRE_CONN_TRY;
314
	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->UnlockScene() );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
315 316
	VAPY_CATCH_RETURN;
};
317

318
static PyObject* va_load_directivity( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
319 320 321 322 323 324 325
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "path", "name", NULL };
	static _PyArg_Parser _parser = { "s|s:load_directivity", _keywords, 0 };
	char* pcPath = nullptr;
	char* pcName = nullptr;
326
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcPath, &pcName ) )
327 328
		return NULL;

329 330
	std::string sName = pcName ? std::string( pcName ) : "";
	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->LoadDirectivity( std::string( pcPath ), sName ) );
331 332 333 334

	VAPY_CATCH_RETURN;
};

335
static PyObject* va_free_directivity( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
336 337 338 339 340 341
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:free_directivity", _keywords, 0 };
	long iID = -1;
342
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
343
		return NULL;
344
	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->FreeDirectivity( iID ) );
345 346 347 348

	VAPY_CATCH_RETURN;
};

349
static PyObject* va_get_directivity_info( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
350 351 352 353 354 355
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_directivity_info", _keywords, 0 };
	long iID = -1;
356
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
357
		return NULL;
358

359
	CVADirectivityInfo oInfo = g_pVANetClient->GetCoreInstance()->GetDirectivityInfo( iID );
360

361
	PyObject* pInfo = Py_BuildValue( "{s:i,s:s,s:s,s:i,s:s}",
362
		"id", oInfo.iID,
363 364
		"name", SaveStringToUnicodeConversion( oInfo.sName ).c_str(),
		"filepath", SaveStringToUnicodeConversion( oInfo.sFilename ).c_str(),
365
		"references", oInfo.iReferences,
366
		"description", SaveStringToUnicodeConversion( oInfo.sDesc ).c_str() );
367 368 369 370 371 372

	return pInfo;

	VAPY_CATCH_RETURN;
};

373
static PyObject* va_get_directivity_infos( PyObject*, PyObject* )
374 375 376 377
{
	VAPY_REQUIRE_CONN_TRY;

	std::vector< CVADirectivityInfo > voInfos;
378
	g_pVANetClient->GetCoreInstance()->GetDirectivityInfos( voInfos );
379

380
	PyObject* pInfoList = PyList_New( voInfos.size() );
381

382
	for( size_t i = 0; i < voInfos.size(); i++ )
383
	{
384 385
		CVADirectivityInfo& oInfo( voInfos[ i ] );
		PyObject* pInfo = Py_BuildValue( "{s:i,s:s,s:s,s:i,s:s}",
386
			"id", oInfo.iID,
387 388
			"name", SaveStringToUnicodeConversion( oInfo.sName ).c_str(),
			"filepath", SaveStringToUnicodeConversion( oInfo.sFilename ).c_str(),
389
			"references", oInfo.iReferences,
390 391
			"description", SaveStringToUnicodeConversion( oInfo.sDesc ).c_str() );
		PyList_SetItem( pInfoList, i, pInfo ); // steals reference
392 393 394 395 396
	}

	return pInfoList;

	VAPY_CATCH_RETURN;
397 398 399
};


400
static PyObject* va_load_hrir( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
401 402 403 404 405 406 407
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "path", "name", NULL };
	static _PyArg_Parser _parser = { "s|s:load_hrir", _keywords, 0 };
	char* pcPath = nullptr;
	char* pcName = nullptr;
408
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcPath, &pcName ) )
409 410
		return NULL;

411 412
	std::string sName = pcName ? std::string( pcName ) : "";
	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->LoadHRIRDataset( std::string( pcPath ), sName ) );
413 414 415 416

	VAPY_CATCH_RETURN;
};

417
static PyObject* va_free_hrir( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
418 419 420 421 422 423
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:free_hrir", _keywords, 0 };
	long iID = -1;
424
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
425
		return NULL;
426
	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->FreeHRIRDataset( iID ) );
427 428 429 430

	VAPY_CATCH_RETURN;
};

431
static PyObject* va_get_hrir_info( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
432 433 434 435 436 437
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_hrir_info", _keywords, 0 };
	long iID = -1;
438
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
439 440
		return NULL;

441 442 443
	CVAHRIRInfo oInfo = g_pVANetClient->GetCoreInstance()->GetHRIRInfo( iID );

	PyObject* pInfo = Py_BuildValue( "{s:i,s:s,s:s,s:i,s:s}",
444
		"id", oInfo.iID,
445 446
		"name", SaveStringToUnicodeConversion( oInfo.sName ).c_str(),
		"filepath", SaveStringToUnicodeConversion( oInfo.sFilename ).c_str(),
447
		"references", oInfo.iReferences,
448
		"description", SaveStringToUnicodeConversion( oInfo.sDesc ).c_str() );
449 450 451 452 453 454

	return pInfo;

	VAPY_CATCH_RETURN;
};

455
static PyObject* va_get_hrir_infos( PyObject*, PyObject* )
456 457 458 459
{
	VAPY_REQUIRE_CONN_TRY;

	std::vector< CVAHRIRInfo > voInfos;
460
	g_pVANetClient->GetCoreInstance()->GetHRIRInfos( voInfos );
461

462
	PyObject* pInfoList = PyList_New( voInfos.size() );
463

464
	for( size_t i = 0; i < voInfos.size(); i++ )
465
	{
466 467
		CVAHRIRInfo& oInfo( voInfos[ i ] );
		PyObject* pInfo = Py_BuildValue( "{s:i,s:s,s:s,s:i,s:s}",
468
			"id", oInfo.iID,
469 470
			"name", SaveStringToUnicodeConversion( oInfo.sName ).c_str(),
			"filepath", SaveStringToUnicodeConversion( oInfo.sFilename ).c_str(),
471
			"references", oInfo.iReferences,
472 473
			"description", SaveStringToUnicodeConversion( oInfo.sDesc ).c_str() );
		PyList_SetItem( pInfoList, i, pInfo ); // steals reference
474 475 476 477 478 479
	}

	return pInfoList;

	VAPY_CATCH_RETURN;
};
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911

static PyObject* va_get_sound_source_ids( PyObject*, PyObject* )
{
	VAPY_REQUIRE_CONN_TRY;
	std::vector< int > viIDs;
	g_pVANetClient->GetCoreInstance()->GetSoundSourceIDs( viIDs );

	PyObject* pIDList = PyList_New( viIDs.size() );
	for( Py_ssize_t i = 0; i < PyList_GET_SIZE( pIDList ); i++ )
		PyList_SetItem( pIDList, i, PyLong_FromLong( viIDs[ i ] ) );

	return pIDList;

	VAPY_CATCH_RETURN;
};

static PyObject* va_create_sound_source( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "name", NULL };
	static _PyArg_Parser _parser = { "s:create_sound_source", _keywords, 0 };
	char* pcName = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcName ) )
		return NULL;

	std::string sName = pcName ? std::string( pcName ) : "PySoundSource";
	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->CreateSoundSource( sName, IVACore::VA_AURAMODE_ALL ) );

	VAPY_CATCH_RETURN;
};


static PyObject* va_create_sound_source_explicit_renderer( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "name", "renderer", NULL };
	static _PyArg_Parser _parser = { "ss:create_sound_source_explicit_renderer", _keywords, 0 };
	char* pcName = nullptr;
	char* pcRenderer = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &pcName, &pcRenderer ) )
		return NULL;

	std::string sRenderer = pcRenderer ? std::string( pcRenderer ) : "Unspecified";
	std::string sName = pcName ? std::string( pcName ) : "PySoundSource_" + sRenderer;
	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->CreateSoundSourceExplicitRenderer( sName, sRenderer ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_delete_sound_source( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:delete_sound_source", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->DeleteSoundSource( iID ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_enabled( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "enabled", NULL };
	static _PyArg_Parser _parser = { "i|b:set_sound_source_enabled", _keywords, 0 };
	long iID = -1;
	bool bEnabled = true;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &bEnabled ) )
		return NULL;

	g_pVANetClient->GetCoreInstance()->SetSoundSourceEnabled( iID, bEnabled );
	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_get_sound_source_enabled( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_enabled", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->GetSoundSourceEnabled( iID ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_get_sound_source_name( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_name", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyUnicode_FromString( SaveStringToUnicodeConversion( g_pVANetClient->GetCoreInstance()->GetSoundSourceName( iID ) ).c_str() );

	VAPY_CATCH_RETURN;
};

static PyObject* va_get_sound_source_signal_source( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_signal_source", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyUnicode_FromString( SaveStringToUnicodeConversion( g_pVANetClient->GetCoreInstance()->GetSoundSourceSignalSource( iID ) ).c_str() );

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_signal_source( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "signalsource", NULL };
	static _PyArg_Parser _parser = { "is:set_sound_source_signal_source", _keywords, 0 };
	long iID = -1;
	char* pcSignalSourceID;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &pcSignalSourceID ) )
		return NULL;

	std::string sSIgnalSourceID = pcSignalSourceID ? std::string( pcSignalSourceID ) : "";
	g_pVANetClient->GetCoreInstance()->SetSoundSourceSignalSource( iID, sSIgnalSourceID );

	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_remove_sound_source_signal_source( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:remove_sound_source_signal_source", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	g_pVANetClient->GetCoreInstance()->RemoveSoundSourceSignalSource( iID );
	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_get_sound_source_auralization_mode( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_auralization_mode", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->GetSoundSourceAuralizationMode( iID ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_auralization_mode( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "auralizationmode", NULL };
	static _PyArg_Parser _parser = { "ii:set_sound_source_auralization_mode", _keywords, 0 };
	long iID = -1;
	long iAuralizationMode = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &iAuralizationMode ) )
		return NULL;

	g_pVANetClient->GetCoreInstance()->SetSoundSourceAuralizationMode( iID, iAuralizationMode );
	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_parameters( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "parameters", NULL };
	static _PyArg_Parser _parser = { "iO!:set_sound_source_parameters", _keywords, 0 };
	long iID = -1;
	PyObject* pParameters = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &pParameters ) )
		return NULL;

	CVAStruct oParameters = ConvertPythonDictToVAStruct( pParameters );
	g_pVANetClient->GetCoreInstance()->SetSoundSourceParameters( iID, oParameters );
	return Py_None;

	VAPY_CATCH_RETURN;
};


static PyObject* va_get_sound_source_parameters( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "io!:get_sound_source_parameters", _keywords, 0 };
	long iID = -1;
	PyObject* pParameters = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &pParameters ) )
		return NULL;

	CVAStruct oParameters = ConvertPythonDictToVAStruct( pParameters );
	CVAStruct oReturn = g_pVANetClient->GetCoreInstance()->GetSoundSourceParameters( iID, oParameters );
	return ConvertVAStructToPythonDict( oReturn );

	VAPY_CATCH_RETURN;
};


static PyObject* va_get_sound_source_directivity( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_directivity", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyLong_FromLong( g_pVANetClient->GetCoreInstance()->GetSoundSourceDirectivity( iID ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_directivity( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "directivity", NULL };
	static _PyArg_Parser _parser = { "ii:set_sound_source_directivity", _keywords, 0 };
	long iID = -1;
	long iDirectivityID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &iDirectivityID ) )
		return NULL;

	g_pVANetClient->GetCoreInstance()->SetSoundSourceDirectivity( iID, iDirectivityID );
	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_get_sound_source_volume( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_volume", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyFloat_FromDouble( g_pVANetClient->GetCoreInstance()->GetSoundSourceVolume( iID ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_volume( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "gain", NULL };
	static _PyArg_Parser _parser = { "id:set_sound_source_volume", _keywords, 0 };
	long iID = -1;
	double dGain = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &dGain ) )
		return NULL;

	g_pVANetClient->GetCoreInstance()->SetSoundSourceVolume( iID, dGain );
	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_muted( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "muted", NULL };
	static _PyArg_Parser _parser = { "i|b:set_sound_source_muted", _keywords, 0 };
	long iID = -1;
	bool bMuted = true;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &bMuted ) )
		return NULL;

	g_pVANetClient->GetCoreInstance()->SetSoundSourceMuted( iID, bMuted );
	return Py_None;

	VAPY_CATCH_RETURN;
};

static PyObject* va_is_sound_source_muted( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:is_sound_source_muted", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	return PyBool_FromLong( g_pVANetClient->GetCoreInstance()->IsSoundSourceMuted( iID ) );

	VAPY_CATCH_RETURN;
};

static PyObject* va_get_sound_source_position( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:va_get_sound_source_position", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	VAVec3 v3Pos;
	g_pVANetClient->GetCoreInstance()->GetSoundSourcePosition( iID, v3Pos.x, v3Pos.y, v3Pos.z );

	PyObject* pPosList = PyList_New( 3 );
	PyList_SetItem( pPosList, 0, PyFloat_FromDouble( v3Pos.x ) );
	PyList_SetItem( pPosList, 1, PyFloat_FromDouble( v3Pos.y ) );
	PyList_SetItem( pPosList, 2, PyFloat_FromDouble( v3Pos.z ) );

	return pPosList;

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_position( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "pos", NULL };
	static _PyArg_Parser _parser = { "i(d,d,d):va_set_sound_source_position", _keywords, 0 };
	long iID = -1;
	PyObject* pPosList = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &pPosList ) )
		return NULL;

	VAVec3 v3Pos;
	v3Pos.x = PyFloat_AsDouble( PyList_GetItem( pPosList, 0 ) );
	v3Pos.y = PyFloat_AsDouble( PyList_GetItem( pPosList, 1 ) );
	v3Pos.z = PyFloat_AsDouble( PyList_GetItem( pPosList, 2 ) );
	g_pVANetClient->GetCoreInstance()->SetSoundSourcePosition( iID, v3Pos.x, v3Pos.y, v3Pos.z );
	return Py_None;

	VAPY_CATCH_RETURN;
};


static PyObject* va_get_sound_source_orientation_vu( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", NULL };
	static _PyArg_Parser _parser = { "i:get_sound_source_orientation_vu", _keywords, 0 };
	long iID = -1;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID ) )
		return NULL;

	VAVec3 v3View, v3Up;
	g_pVANetClient->GetCoreInstance()->GetSoundSourceOrientationVU( iID, v3View.x, v3View.y, v3View.z, v3Up.x, v3Up.y, v3Up.z );

	PyObject* pViewList = PyList_New( 3 );
	PyList_SetItem( pViewList, 0, PyFloat_FromDouble( v3View.x ) );
	PyList_SetItem( pViewList, 1, PyFloat_FromDouble( v3View.y ) );
	PyList_SetItem( pViewList, 2, PyFloat_FromDouble( v3View.z ) );

	PyObject* pUpList = PyList_New( 3 );
	PyList_SetItem( pUpList, 0, PyFloat_FromDouble( v3View.x ) );
	PyList_SetItem( pUpList, 1, PyFloat_FromDouble( v3View.y ) );
	PyList_SetItem( pUpList, 2, PyFloat_FromDouble( v3View.z ) );

	PyObject* pViewUpList = PyList_New( 2 );
	PyList_SetItem( pUpList, 0, pViewList );
	PyList_SetItem( pUpList, 1, pUpList );
	return pViewUpList;

	VAPY_CATCH_RETURN;
};

static PyObject* va_set_sound_source_orientation_vu( PyObject*, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames )
{
	VAPY_REQUIRE_CONN_TRY;

	static const char * const _keywords[] = { "id", "view", "up", NULL };
	static _PyArg_Parser _parser = { "i(d,d,d)(d,d,d):set_sound_source_orientation_vu", _keywords, 0 };
	long iID = -1;
	PyObject* pViewList = nullptr;
	PyObject* pUpList = nullptr;
	if( !_PyArg_ParseStack( ppArgs, nArgs, pKeywordNames, &_parser, &iID, &pViewList, &pUpList ) )
		return NULL;

	VAVec3 v3View;
	v3View.x = PyFloat_AsDouble( PyList_GetItem( pViewList, 0 ) );
	v3View.y = PyFloat_AsDouble( PyList_GetItem( pViewList, 1 ) );
	v3View.z = PyFloat_AsDouble( PyList_GetItem( pViewList, 2 ) );

	VAVec3 v3Up;
	v3Up.x = PyFloat_AsDouble( PyList_GetItem( pUpList, 0 ) );
	v3Up.y = PyFloat_AsDouble( PyList_GetItem( pUpList, 1 ) );
	v3Up.z = PyFloat_AsDouble( PyList_GetItem( pUpList, 2 ) );

	g_pVANetClient->GetCoreInstance()->SetSoundSourceOrientationVU( iID, v3View.x, v3View.y, v3View.z, v3Up.x, v3Up.y, v3Up.z );
	return Py_None;

	VAPY_CATCH_RETURN;
};