Finishing update methods for PTGenericPath renderer example

parent df46bdaa
......@@ -21,7 +21,7 @@
},
{
"cell_type": "code",
"execution_count": 42,
"execution_count": 34,
"metadata": {},
"outputs": [
{
......@@ -30,14 +30,6 @@
"text": [
"Connected.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"c:\\users\\jonas\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\ipykernel_launcher.py:5: RuntimeWarning: Was still connected, forced disconnect.\n",
" \"\"\"\n"
]
}
],
"source": [
......@@ -65,7 +57,7 @@
},
{
"cell_type": "code",
"execution_count": 43,
"execution_count": 35,
"metadata": {},
"outputs": [
{
......@@ -93,22 +85,46 @@
},
{
"cell_type": "code",
"execution_count": 44,
"execution_count": 120,
"metadata": {},
"outputs": [
{
"data": {
"text/markdown": [
"\n",
" --- GenericPath renderer instance 'PrototypeGenericPath:Experimental' ---\n",
"\n",
"[help]\n",
"If the call module struct contains a key with the name 'help', this help text will be shown and the return struct will be returned with the key name 'help'.\n",
"\n",
"[info]\n",
"If the call module struct contains a key with the name 'info', information on the static configuration of the renderer will be returned.\n",
"\n",
"[update]\n",
"For every successful path update, the VA source and listener ID has to be passed like this:\n",
" listener: <int>, the number of the listener identifier\n",
" source: <int>, the number of the source identifier\n",
"\n",
"Updating the path filter (impulse response in time domain) for a listener and a source can be performed in two ways:\n",
" a) using a path to a multi-channel WAV file:\n",
" Provide a key with the name 'filepath' and the path to the WAV file (absolute or containing the macro '$(VADataDir)' or relative to the executable) [priority given to 'filepath' if b) also applies]\n",
" b) sending floating-point data for each channel\n",
" Provide a key for each channel with the generic name 'ch#', where the hash is substituted by the actual number of channel (starting at 1), and the value to this key will contain floating point data (or a sample buffer). The call parameter struct does not necessarily have to contain all channels, also single channels will be updated if key is given.\n",
"\n",
"Note: the existence of the key 'verbose' will print update information at server console and will provide the update info as an 'info' key in the returned struct.\n"
],
"text/plain": [
"{'help': \"\\n --- GenericPath renderer instance 'PrototypeGenericPath:Experimental' ---\\n\\n[help]\\nIf the call module struct contains a key with the name 'help', this help text will be shown and the return struct will be returned with the key name 'help'.\\n\\n[info]\\nIf the call module struct contains a key with the name 'info', information on the static configuration of the renderer will be returned.\\n\\n[update]\\nFor every successful path update, the VA source and listener ID has to be passed like this:\\n listener: <int>, the number of the listener identifier\\n source: <int>, the number of the source identifier\\n\\nUpdating the path filter (impulse response in time domain) for a listener and a source can be performed in two ways:\\n a) using a path to a multi-channel WAV file:\\n Provide a key with the name 'filepath' and the path to the WAV file (absolute or containing the macro '$(VADataDir)' or relative to the executable) [priority given to 'filepath' if b) also applies]\\n b) sending floating-point data for each channel\\n Provide a key for each channel with the generic name 'ch#', where the hash is substituted by the actual number of channel (starting at 1), and the value to this key will contain floating point data (or a sample buffer). The call parameter struct does not necessarily have to contain all channels, also single channels will be updated if key is given.\\n\\nNote: the existence of the key 'verbose' will print update information at server console and will provide the update info as an 'info' key in the returned struct.\\n\"}"
"<IPython.core.display.Markdown object>"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
"output_type": "display_data"
}
],
"source": [
"va.call_module( rmod_name, {} )"
"rmod_generic_info = va.call_module( rmod_name, {} )\n",
"from IPython.display import Markdown, display\n",
"display( Markdown( rmod_generic_info[ 'help' ] ) )"
]
},
{
......@@ -152,7 +168,7 @@
},
{
"cell_type": "code",
"execution_count": 46,
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
......@@ -172,7 +188,7 @@
},
{
"cell_type": "code",
"execution_count": 47,
"execution_count": 37,
"metadata": {},
"outputs": [
{
......@@ -204,7 +220,7 @@
},
{
"cell_type": "code",
"execution_count": 51,
"execution_count": 134,
"metadata": {},
"outputs": [
{
......@@ -234,7 +250,7 @@
},
{
"cell_type": "code",
"execution_count": 61,
"execution_count": 135,
"metadata": {},
"outputs": [
{
......@@ -263,7 +279,7 @@
},
{
"cell_type": "code",
"execution_count": 59,
"execution_count": 125,
"metadata": {},
"outputs": [
{
......@@ -286,7 +302,7 @@
},
{
"cell_type": "code",
"execution_count": 57,
"execution_count": 136,
"metadata": {},
"outputs": [
{
......@@ -301,6 +317,79 @@
"msg = va.call_module( rmod_name, update_filepath )\n",
"print( msg[ 'info' ] )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Update by loading samples into Python and transmit IR\n",
"If you want to load an manipulate samples using Python, you can do the following. Make sure that the file is in the same folder of this notebook, or modify path accordingly.\n",
"\n",
"You can use `scipy` or `wave` to obtain data from a WAVE file, however sample type conversion might be an issue because they usually only provide integer type, and VA requires floating point samples. In this example, the input file is a 24bit signed integer."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loaded an impulse response of 2 channel(s) with 264600 filter taps.\n"
]
}
],
"source": [
"import wave, struct\n",
"w = wave.open( 'stalbans_a_binaural.wav' )\n",
"raw_ir = w.readframes( w.getnframes() )\n",
"ir_length = w.getnframes()\n",
"ir_channels = w.getnchannels()\n",
"assert( w.getsampwidth() == 3 )\n",
"\n",
"# Deinterleave and convert sample type (slow implementation, but more easy to interpret)\n",
"ir = list()\n",
"for n in range( ir_channels ) :\n",
" ir.append( [] )\n",
" for i in range( ir_length ) :\n",
" rbegin = 3 * ( n + i * ir_channels + 0 )\n",
" rend = 3 * ( n + i * ir_channels + 1 )\n",
" sample_sint24 = raw_ir[ rbegin : rend ]\n",
" sample_sint32 = sample_sint24 + ( b'\\0' if sample_sint24[2] < 128 else b'\\xff' )\n",
" sample_float = ( struct.unpack( 'i', sample_sint32 )[0] ) / pow( 2, 24 - 1 )\n",
" ir[ n ].append( sample_float )\n",
"\n",
"print( 'Loaded an impulse response of %i channel(s) with %i filter taps.' % ( len( ir ), len( ir[ 0 ] ) ) )"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Updated sound path <L1, S1, C1> with 88200 new samples\n",
"Updated sound path <L1, S1, C2> with 88200 new samples\n"
]
}
],
"source": [
"update_ir = dict()\n",
"update_ir[ 'listener' ] = listener_id\n",
"update_ir[ 'source' ] = sound_source_id\n",
"update_ir[ 'ch1' ] = ir[ 0 ]; # Requires ir samples to be floating point, so sample type conversion might be required\n",
"update_ir[ 'ch2' ] = ir[ 1 ]; # Requires ir samples to be floating point, so sample type conversion might be required\n",
"update_ir[ 'verbose' ] = True;\n",
"\n",
"msg = va.call_module( rmod_name, update_ir )\n",
"print( msg[ 'info_ch1'] )\n",
"print( msg[ 'info_ch2'] )"
]
}
],
"metadata": {
......@@ -308,18 +397,6 @@
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
}
},
"nbformat": 4,
......
......@@ -18,18 +18,9 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Current working directory: C:\\dev\\VA\\dist\\win32-x64.vc14\\python\\examples\\jupyter\n",
"Successfully loaded VA Python extension\n"
]
}
],
"outputs": [],
"source": [
"import sys\n",
"sys.path.append( '../../Lib/site-packages' )\n",
......@@ -48,22 +39,12 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": null,
"metadata": {},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (<ipython-input-28-20070eb91885>, line 1)",
"output_type": "error",
"traceback": [
"\u001b[1;36m File \u001b[1;32m\"<ipython-input-28-20070eb91885>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m if not va.connect( 'localhost' )\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
]
}
],
"outputs": [],
"source": [
"if not va.connect( 'localhost' )\n",
" raise 'Could not connect to server on localhost, not running?'\n",
" "
"if not va.connect( 'localhost' ) :\n",
" raise 'Could not connect to server on localhost, not running?'"
]
},
{
......@@ -75,7 +56,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": null,
"metadata": {
"collapsed": true
},
......@@ -93,7 +74,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": null,
"metadata": {
"collapsed": true
},
......@@ -112,13 +93,12 @@
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": true
},
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"va.add_search_path( os.getcwd() );"
"va.add_search_path( os.getcwd() );\n",
"va.add_search_path( 'C:\\dev\\VA\\VACore\\data' )"
]
},
{
......@@ -131,10 +111,8 @@
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": true
},
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"signal_source_id = va.create_audio_file_signal_source( 'Audiofiles/Bauer.wav' )\n",
......@@ -152,7 +130,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": null,
"metadata": {
"collapsed": true
},
......@@ -172,7 +150,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": null,
"metadata": {
"collapsed": true
},
......@@ -192,10 +170,8 @@
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": true
},
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hrir_id = va.load_hrir( '$(DefaultHRIR)' )"
......@@ -211,21 +187,9 @@
},
{
"cell_type": "code",
"execution_count": 25,
"execution_count": null,
"metadata": {},
"outputs": [
{
"ename": "Exception",
"evalue": "Modal error: Not connected. (error code 3)",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-25-f668a5e697e7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mlistener_id\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mva\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcreate_listener\u001b[0m\u001b[1;33m(\u001b[0m \u001b[1;34m'PyListener'\u001b[0m \u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mva\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_listener_position\u001b[0m\u001b[1;33m(\u001b[0m \u001b[0mlistener_id\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1.7\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;33m)\u001b[0m \u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mva\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_listener_orientation_vu\u001b[0m\u001b[1;33m(\u001b[0m \u001b[0mlistener_id\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;33m)\u001b[0m \u001b[1;33m)\u001b[0m \u001b[1;31m# Default view is to -Z (OpenGL)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mva\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_listener_hrir\u001b[0m\u001b[1;33m(\u001b[0m \u001b[0mlistener_id\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mhrir_id\u001b[0m \u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mException\u001b[0m: Modal error: Not connected. (error code 3)"
]
}
],
"outputs": [],
"source": [
"listener_id = va.create_listener( 'PyListener' )\n",
"va.set_listener_position( listener_id, ( 0, 1.7, 0 ) )\n",
......@@ -243,7 +207,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": null,
"metadata": {
"collapsed": true
},
......@@ -261,7 +225,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": null,
"metadata": {
"collapsed": true
},
......@@ -269,6 +233,15 @@
"source": [
"va.disconnect();"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment