Commit 266be3d5 authored by henryjandrew's avatar henryjandrew
Browse files

updated VA_example_ppa to read in json files and extract data from them to be...

updated VA_example_ppa to read in json files and extract data from them to be pushed to the outdoor noise renderer
parent e53e1c18
......@@ -7,7 +7,7 @@
% Requires ITA-Toolbox, obtain from http://www.ita-toolbox.org
ppa_folder = '../../../ITAGeometricalAcoustics/ITAPropagationPathSim/tests/CombinedModel/UrbanTrajectory';
ppa_diffraction_model = 'utd';
%% Preps
......@@ -41,6 +41,9 @@ va.set_signal_source_buffer_playback_action( X, 'play' )
va.set_signal_source_buffer_looping( X, true );
va.set_sound_source_signal_source( S, X )
path_identifiers = containers.Map('KeyType','char','ValueType','uint16'); %a map linking the path number to name
path_status = cell(1); %cell array indexed by path number containing a struct with onfo on path
path_count = 0; %The total number of paths, NOTE -NOT a count of paths in current frame, if paths are deleted, they are not removed from this count
%% Run synchronized scene update & audio processing simulation/auralization
......@@ -58,46 +61,78 @@ for n = 1:N
% Load propagation paths for current frame
ppa_file_path = fullfile( file_listing( n ).folder, file_listing( n ).name );
pps = ita_propagation_load_paths( ppa_file_path )
pps = ita_propagation_load_paths( ppa_file_path ); %pps = struct containing the current time frame
% Update source (first anchor)
source_pos = pps( n ).propagation_anchors{ 1 }.interaction_point; % OpenGL coordinates?! -> transform using
source_pos_OpenGL = ita_matlab2openGL( source_pos );
source_pos_OpenGL = ita_matlab2openGL( source_pos(1:3)' );
va.set_sound_source_position( S, source_pos_OpenGL );
% Update receiver (last anchor)
receiver_pos = pps( n ).propagation_anchors{ end }.interaction_point; % OpenGL coordinates?! -> transform using
receiver_pos_OpenGL = ita_matlab2openGL( receiver_pos );
receiver_pos_OpenGL = ita_matlab2openGL( receiver_pos(1:3)' );
va.set_sound_receiver_position( R, source_pos_OpenGL );
paths_update = struct();
for p = 1:numel( pps )
pp = pps( n ); % Propagation path
pp = pps( p ).propagation_anchors; % Propagation path
pu = struct(); % Path update
% Assemble DSP settings (gain, delay & filter coefficients)
pu.source = S;
pu.receiver = R;
pu.ID = pp.ID; % string -> int ID lookup required
pu.path = strcat( 'direct_', num2str(S), '_to_', num2str(R) ); %sound path ID
path_name = get_path(pp);
pu.path = path_name;
pu.gain = 1 / ita_propagation_path_attenuation( pp );
pu.delay = ita_propagation_path_length( pp ) / c;
pu.frequencies = f;
pu.frequency_magnitudes = ita_propagation_path_filter( pp, f );
exists = isKey( path_identifiers, path_name );
if( ~exists ) %if path does not already exist, add a new path with a unique int ID
path_count = path_count + 1;
ID = path_count;
new_ID = struct;
new_ID.ID = ID;
new_ID.updated = true;
new_ID.deleted = false;
new_ID.name = path_name;
path_status{ID} = new_ID;
path_identifiers(path_name) = ID;
else
ID = path_identifiers(path_name);
path_status{ID}.updated = true; %if path already exists, mark that it has been updated
end
pu.position = pp{ end-1 }.interaction_point; % next to last anchor
pu.ID = ID;
%pu.path = strcat( 'direct_', num2str(S), '_to_', num2str(R) ); %sound path ID
pu.delete = false; %set to true when an existing path should be deleted
[frequency_mags, gain, delay] = ita_get_propagation_path_data( pp, f, c);
pu.gain = gain;
pu.delay = delay;
pu.frequency_magnitudes = frequency_mags;
pu.frequencies = f;
pu.position = pp{ end-1 }.interaction_point; % next to last anchor
pu.delete = false;
pu.audible = true;
paths_upate( n ) = pu;
paths_upate.(strcat('prop_path_',num2str(p))) = pu; %create a new field in the update struct containing the new path data
end
for i = 1:numel(path_status) %add any paths which need to be deleted to the update struct
if( (path_status{i}.updated == false) && (path_status{i}.deleted == false) )
p = p + 1;
dpu = struct();
dpu.ID = i;
dpu.delete = true;
paths_upate.(strcat('prop_path_',num2str(p))) = dpu; %set a new field in the path update struct telling the renderer to delete the path which no longer appears
path_status{i}.deleted = true;
end
path_status{i}.updated = false;
end
% Update all propagation paths
va.set_rendering_module_parameters( 'MyBinauralOutdoorNoise', paths_upate );
......@@ -108,7 +143,7 @@ for n = 1:N
% Process audio chain by incrementing one block
va.call_module( 'virtualaudiodevice', struct( 'trigger', true ) );
waitbar( n / numsteps )
waitbar( n / N )
end
close( h )
......@@ -116,3 +151,75 @@ close( h )
va.disconnect
disp( 'Stop VA to export simulation results from rendering module(s)' )
%%
function path_name = get_path( path_struct )
num_interactions = numel( path_struct );
path_name = '';
for i = 1:num_interactions
switch path_struct{i}.anchor_type
case 'source'
ID = path_struct{i}.name;
path_name = strcat( path_name, 'SRC', num2str(ID), '_' );
case 'receiver'
ID = path_struct{i}.name;
path_name = strcat( path_name, 'RCVR', num2str(ID) );
case 'specular_reflection'
ID = path_struct{i}.polygon_id;
path_name = strcat( path_name, 'SR', num2str(ID), '_' );
case 'outer_edge_diffraction'
ID1 = path_struct{i}.main_wedge_face_id;
ID2 = path_struct{i}.opposite_wedge_face_id;
path_name = strcat( path_name, 'EDMF', num2str(ID1), 'OF', num2str(ID2), '_' );
end
end
end
function [frequency_mags, gain, delay] = ita_get_propagation_path_data( path_struct, f, c )
gain = 1;
frequency_mags = ones(1,length(f));
total_distance = 0;
last_diff_distance = 0;
last_diff = 1; %marks the last place place there was a diffraction or source
for i = 2:numel(path_struct)-1 %start from 2, first entry is always source, -1 as receiver always the last
anchor_type = path_struct{i}.anchor_type;
segment_distance = norm(path_struct{ i }.interaction_point(1:3) - path_struct{ i-1 }.interaction_point(1:3));
total_distance = total_distance + segment_distance;
last_diff_distance = last_diff_distance + segment_distance; %tracks the distance form the last diff point/ source
switch anchor_type
case 'outer_edge_diffraction' %case for diffraction
main_face_normal = path_struct{i}.main_wedge_face_normal(1:3);
opposite_face_normal = path_struct{i}.opposite_wedge_face_normal(1:3);
apex = path_struct{i}.interaction_point(1:3); %aperture point
vertex_length = norm( path_struct{i}.vertex_start(1:3) - path_struct{i}.vertex_end(1:3) );
%wedge_type = path_struct{i}.anchor_type; %FOR NOW ALWAYS USE THE DEFAULT WEDGE TYPE
w = itaFiniteWedge( main_face_normal, opposite_face_normal, apex, vertex_length );
first = path_struct{last_diff}.interaction_point(1:3); %"source"
second = path_struct{i+1}.interaction_point(1:3); %"receiver"
[~, D, A] = ita_diffraction_utd( w, first, second, f, c );
gain = gain * (A / last_diff_distance);
frequency_mags = frequency_mags .* D;
last_diff = i;
last_diff_distance = 0;
case 'specular_reflection' %case for specular reflection
%frequency_mags = frequency_mags .* FREQ_DATA_FOR_REFLECTION_SURFACE; %INSERT LOOKUP FIR FREQ DATA BASED ON VERTEX NUMBER
otherwise
error('Unrecognised anchor type');
end
end
frequency_mags = frequency_mags .* ita_atmospheric_absorption_factor( f, total_distance ); %flter contribution from atmospheric absorption
if( last_diff_distance ~= 0 ) %if the last anchor was not diffraction
gain = gain * (1/last_diff_distance);
end
delay = total_distance / c;
end
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