VA_example_outdoor_acoustics.m 5.35 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
%% VA offline simulation/auralization example for an outdoor noise scenario

% Requires VA to run with a virtual audio device that can be triggered by
% the user. Also the generic path prototype rendering module(s) has to record the output
% to hard drive.


%% Connect and set up simple scene
va = VA( 'localhost' );

c = va.get_homogeneous_medium_sound_speed();
f = ita_ANSI_center_frequencies;

L = va.create_sound_receiver( 'VA_Listener' );
receiver_pos = [ 2 1.7 0 ]; % OpenGL coordinates
va.set_sound_receiver_position( L, receiver_pos )
17 18
%H = va.create_directivity_from_file( '$(DefaultHRIR)' );
H = va.create_directivity_from_file( 'D:/Users/andrew/dev/ITASuite/VA/VAMatlab/matlab/ITA_Artificial_Head_5x5_44kHz_128.v17.ir.daff' );
19
interp1(
20 21 22
va.set_sound_receiver_directivity( L, H );

S = va.create_sound_source( 'VA_Source' );
23 24 25
%X = va.create_signal_source_buffer_from_file( '$(DemoSound)' );
X = va.create_signal_source_buffer_from_file( 'D:/Users/andrew/dev/ITASuite/VA/VAMatlab/matlab/WelcomeToVA.wav' );

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
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 )

% House corner
w = itaFiniteWedge( [ 1 0 0 ], [ 0 0 -1 ], [ 0 -2 0 ], 4 ); % OpenGL coordinates

%% Example for a synchronized scene update & audio processing simulation/auralization

timestep = 128 / 44100; % here: depends on block size and sample rate
manual_clock = 0;
va.set_core_clock( 0 );

spatialstep = 0.1;
disp( [ 'Resulting sound source speed: ' num2str( spatialstep / timestep ) ' m/s' ] )

numsteps = 3400;
disp( [ 'Simulation result duration: ' num2str( numsteps * timestep ) ' s' ] )

x = linspace( -1, 1, numsteps ) * 50; % motion from x = -5m to x = 5m

47 48
n0_of_paths = 2;

49
h = waitbar( 0, 'Hold on, running auralization' );
50
direct_deleted = false; %set to true when the direct path has been deleted
51 52 53 54 55 56 57 58 59 60
for n = 1:length( x )
    
    % Modify scene as you please (position has no real effect for prototype generic path renderer)
    source_pos = [ x( n ) 1.1 -3 ]; % OpenGL coordinates
    distance = sum( abs( source_pos - receiver_pos ) );
    va.set_sound_source_position( S, source_pos );    
    
    
    % Manually create direct sound path and diffracted sound path
    
61 62 63 64 65 66 67 68 69 70 71 72 73
    shadow_zone = ita_diffraction_shadow_zone(w, source_pos, receiver_pos); %is receiver in shadow zone?
    
    if( shadow_zone == false )
        prop_path_direct = struct();
        
        prop_path_direct.distance = distance;
        prop_path_direct.delay = distance / c; %delay from sound emitting from source to being received at listener
        prop_path_direct.frequencies = f; %Frequencies corresponding to the mags
        values = ones(1,31);
        prop_path_direct.frequency_magnitudes = values;
        prop_path_direct.source = S; %sound source ID
        prop_path_direct.receiver = L; %sound receiver ID
        prop_path_direct.path = strcat( 'direct_', num2str(S), '_to_', num2str(L) ); %sound path ID
74
        prop_path_direct.ID = 0;
75
        prop_path_direct.delete = false; %set to true when the path should be deleted
76
        prop_path_direct.position = source_pos;
77 78
        direct_deleted = false;
        
79
    else
80
        prop_path_direct = struct();
81
        prop_path_direct.ID = 0;
82 83 84
        prop_path_direct.path = strcat( 'direct_', num2str(S), '_to_', num2str(L) ); %sound path ID
        prop_path_direct.delete = true; %if source is in shadow zone, delete direct path
        direct_deleted = true;
85 86
    end
    
87 88 89 90
    
    %maybe use this to fade out direct sound by setting distance to inf or
    %seting flter to 0
    
91
    apex = w.get_aperture_point( source_pos, receiver_pos );
92
    detour = norm( source_pos - apex ) + norm(apex - receiver_pos );    
93 94
    
    prop_path_diffracted = struct();
95
    
96 97 98
    prop_path_diffracted.distance = detour;
    prop_path_diffracted.delay = detour / c;
    prop_path_diffracted.frequencies = f;
99 100 101 102
    values = abs( ita_diffraction_utd( w, source_pos, receiver_pos, f, c ) );
    prop_path_diffracted.frequency_magnitudes = values';
    prop_path_diffracted.source = S;
    prop_path_diffracted.receiver = L;
103
    prop_path_diffracted.ID = 1;
104 105
    prop_path_diffracted.path = strcat( 'diff1_', num2str(S), '_to_', num2str(L) );
    prop_path_diffracted.delete = false;
106
    prop_path_diffracted.position = apex;
107 108
    
    % @todo at some point: load all paths from pre-calculated simulation -> ITAPropagationPathSim (C++) output
109
    % D:/Users/andrew/dev/ITASuite/VA/VACore/tests/BinauralOutdoorNoiseRendererTest.VACore.ini
110
    disp(strcat('**diff dirn: ', num2str(apex),' Delay = ',num2str(distance/c),'** Direct sound: ',num2str(source_pos),' Delay = ',num2str(detour/c),'**'));
111 112 113
    
    % Update wave fronts in renderer
    path_update = struct();
114 115 116 117 118 119
    if( direct_deleted == false )
        path_update.prop_path_0 = prop_path_direct;
        path_update.prop_path_1 = prop_path_diffracted;
    else
        path_update.prop_path_0 = prop_path_diffracted;
    end
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    va.set_rendering_module_parameters( 'MyBinauralOutdoorNoise', path_update );
    
    % Increment core clock
    manual_clock = manual_clock + timestep;
    va.call_module( 'manualclock', struct( 'time', manual_clock ) );
    
    % Process audio chain by incrementing one block
    va.call_module( 'virtualaudiodevice', struct( 'trigger', true ) );
    
    waitbar( n / numsteps )
    
end
close( h )

va.disconnect

disp( 'Stop VA to export simulation results from rendering module(s)' )