Commit e3fed933 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

WIP

parent 8309c838
%% VA offline simulation/auralization example for an outdoor noise scenario %% VA offline simulation/auralization example for an outdoor noise scenario
% Requires VA to run with a virtual audio device that can be triggered by % 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 % the user. Also the generic path prototype rendering module(s) has to record the output
% to hard drive. % to hard drive.
free_field_only = false; % Now occlusion and no reflections free_field_only = false; % Now occlusion and no reflections
direct_field_component = true; direct_field_component = true;
reflected_field_component = true; reflected_field_component = true;
diffracted_field_component = true; diffracted_field_component = true;
receiver_pos = [ 3 0 3 ]; % OpenGL coordinates receiver_pos = [ 3 0 3 ]; % OpenGL coordinates
f = ita_ANSI_center_frequencies; f = ita_ANSI_center_frequencies;
% House corner % House corner
w = itaInfiniteWedge( [ 1 0 0 ], [ 0 0 -1 ], [ 0 0 0 ] ); % OpenGL coordinates w = itaInfiniteWedge( [ 1 0 0 ], [ 0 0 -1 ], [ 0 0 0 ] ); % OpenGL coordinates
%% Connect and set up simple scene %% Connect and set up simple scene
va = VA; va = VA;
try try
va.connect; va.connect;
dry_run = ~va.get_connected; dry_run = ~va.get_connected;
va.add_search_path( 'D:/Users/andrew/dev/ITASuite/VA/VACore/data' ); va.add_search_path( 'D:/Users/andrew/dev/ITASuite/VA/VACore/data' );
va.add_search_path( 'D:/Users/andrew/dev/ITASuite/VA/VAMatlab/matlab' ); va.add_search_path( 'D:/Users/andrew/dev/ITASuite/VA/VAMatlab/matlab' );
va.add_search_path( 'C:/dev/VA/VACore/data' ); va.add_search_path( 'C:/dev/VA/VACore/data' );
va.add_search_path( 'D:/Users/stienen/dev/VA/VACore/data' ); va.add_search_path( 'D:/Users/stienen/dev/VA/VACore/data' );
va.add_search_path( 'C:/ITASoftware/Raven/RavenDatabase/SoundDatabase' ); va.add_search_path( 'C:/ITASoftware/Raven/RavenDatabase/SoundDatabase' );
va.add_search_path( 'C:\Users\jonas\sciebo\ITA\Lehre\Masterarbeiten\2019 Henry Andrew\car_pass-by_corner' ); va.add_search_path( 'C:\Users\jonas\sciebo\ITA\Lehre\Masterarbeiten\2019 Henry Andrew\car_pass-by_corner' );
c = va.get_homogeneous_medium_sound_speed(); c = va.get_homogeneous_medium_sound_speed();
L = va.create_sound_receiver( 'VA_Listener' ); L = va.create_sound_receiver( 'VA_Listener' );
va.set_sound_receiver_position( L, receiver_pos ) va.set_sound_receiver_position( L, receiver_pos )
%H = va.create_directivity_from_file( '$(DefaultHRIR)' ); %H = va.create_directivity_from_file( '$(DefaultHRIR)' );
H = va.create_directivity_from_file( 'ITA-Kunstkopf_HRIR_AP11_Pressure_Equalized_3x3_256.v17.ir.daff' ); H = va.create_directivity_from_file( 'ITA-Kunstkopf_HRIR_AP11_Pressure_Equalized_3x3_256.v17.ir.daff' );
va.set_sound_receiver_directivity( L, H ); va.set_sound_receiver_directivity( L, H );
S = va.create_sound_source( 'VA_Source' ); S = va.create_sound_source( 'VA_Source' );
%X = va.create_signal_source_buffer_from_file( 'WelcomeToVA.wav' ); %X = va.create_signal_source_buffer_from_file( 'WelcomeToVA.wav' );
X = va.create_signal_source_buffer_from_file( 'LKW Leerlauf 2.wav' ); X = va.create_signal_source_buffer_from_file( 'LKW Leerlauf 2.wav' );
%X = va.create_signal_source_buffer_from_file( 'Full song - Vulfpeck - Dean Town.wav' ); %X = va.create_signal_source_buffer_from_file( 'Full song - Vulfpeck - Dean Town.wav' );
va.set_signal_source_buffer_playback_action( X, 'play' ) va.set_signal_source_buffer_playback_action( X, 'play' )
va.set_signal_source_buffer_looping( X, true ); va.set_signal_source_buffer_looping( X, true );
va.set_sound_source_signal_source( S, X ) va.set_sound_source_signal_source( S, X )
catch catch
dry_run = true; dry_run = true;
c = 343; c = 343;
S = -1; S = -1;
L = -1; L = -1;
end end
k = 2 * pi * freq ./ c; k = 2 * pi * f ./ c;
%% Example for a synchronized scene update & audio processing simulation/auralization %% Example for a synchronized scene update & audio processing simulation/auralization
timestep = 128 / 44100; % here: depends on block size and sample rate timestep = 128 / 44100; % here: depends on block size and sample rate
manual_clock = 0; manual_clock = 0;
if ~dry_run if ~dry_run
va.set_core_clock( 0 ); va.set_core_clock( 0 );
end end
spatialstep = 0.1 / 2; spatialstep = 0.1 / 2;
disp( [ 'Resulting sound source speed: ' num2str( spatialstep / timestep ) ' m/s' ] ) disp( [ 'Resulting sound source speed: ' num2str( spatialstep / timestep ) ' m/s' ] )
numsteps = 3400 * 2; numsteps = 3400 * 2;
disp( [ 'Simulation result duration: ' num2str( numsteps * timestep ) ' s' ] ) disp( [ 'Simulation result duration: ' num2str( numsteps * timestep ) ' s' ] )
x = linspace( -1, 1, numsteps ) * 20; % motion from x = -50m to x = 50m x = linspace( -1, 1, numsteps ) * 20; % motion from x = -50m to x = 50m
H_direct_log = []; H_direct_log = [];
H_diffracted_log = []; H_diffracted_log = [];
H_reflected_log = []; H_reflected_log = [];
H_total_field_log = []; H_total_field_log = [];
IL_log = []; % Insertion loss IL_log = []; % Insertion loss
h = waitbar( 0, 'Hold on, running auralization' ); h = waitbar( 0, 'Hold on, running auralization' );
direct_deleted = false; %set to true when the direct path has been deleted direct_deleted = false; %set to true when the direct path has been deleted
for n = 1:length( x ) for n = 1:length( x )
source_pos = [ x( n ) 0 -3 ]; % OpenGL coordinates source_pos = [ x( n ) 0 -3 ]; % OpenGL coordinates
if ~dry_run if ~dry_run
va.set_sound_source_position( S, source_pos ); va.set_sound_source_position( S, source_pos );
end end
%% Direct sound path %% Direct sound path
% Manually create direct sound path and diffracted sound path % Manually create direct sound path and diffracted sound path
shadow_zone = ita_diffraction_shadow_zone( w, source_pos, receiver_pos ); %is receiver in shadow zone? shadow_zone = ita_diffraction_shadow_zone( w, source_pos, receiver_pos ); %is receiver in shadow zone?
if n > 1 && last_shadow_zone ~= shadow_zone if n > 1 && last_shadow_zone ~= shadow_zone
fprintf( 'Shadow zone boundary has been crossed on frame %i (time %.2f)\n', n, n * timestep ) fprintf( 'Shadow zone boundary has been crossed on frame %i (time %.2f)\n', n, n * timestep )
end end
last_shadow_zone = shadow_zone; last_shadow_zone = shadow_zone;
distance = norm( source_pos - receiver_pos ); distance = norm( source_pos - receiver_pos );
prop_path_direct = struct(); prop_path_direct = struct();
prop_path_direct.identifier = 'direct_path'; prop_path_direct.identifier = 'direct_path';
prop_path_direct.gain = 1 / distance; prop_path_direct.gain = 1 / distance;
prop_path_direct.delay = distance / c; %delay from sound emitting from source to being received at listener 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 prop_path_direct.frequencies = f; %Frequencies corresponding to the mags
values = ones(1,31); values = ones(1,31);
prop_path_direct.frequency_magnitudes = values; prop_path_direct.frequency_magnitudes = values;
prop_path_direct.source = S; %sound source ID prop_path_direct.source = S; %sound source ID
prop_path_direct.receiver = L; %sound receiver ID prop_path_direct.receiver = L; %sound receiver ID
prop_path_direct.delete = false; %set to true when an existing path should be deleted prop_path_direct.delete = false; %set to true when an existing path should be deleted
prop_path_direct.position = source_pos; prop_path_direct.position = source_pos;
if free_field_only if free_field_only
prop_path_direct.audible = true; % Free field: always audible prop_path_direct.audible = true; % Free field: always audible
else else
prop_path_direct.audible = ~shadow_zone; % Direct field: may be occluded prop_path_direct.audible = ~shadow_zone; % Direct field: may be occluded
end end
H_direct = 1 ./ distance .* exp( -1i .* k .* distance ); H_direct = 1 ./ distance .* exp( -1i .* k .* distance );
%% Diffracted sound path %% Diffracted sound path
apex = w.get_aperture_point( source_pos, receiver_pos ); apex = w.get_aperture_point( source_pos, receiver_pos );
detour = norm( source_pos - apex ) + norm( apex - receiver_pos ); detour = norm( source_pos - apex ) + norm( apex - receiver_pos );
H_diffracted = ita_diffraction_utd( w, source_pos, receiver_pos, f, c ); [ H_diffracted, D, A ] = ita_diffraction_utd( w, source_pos, receiver_pos, f, c );
[ ~, D, A ] = ita_diffraction_utd( w, source_pos, receiver_pos, f, c ); rho = norm( apex - source_pos );
rho = norm( apex - source_pos );
prop_path_diffracted = struct();
prop_path_diffracted = struct(); prop_path_diffracted.source = S;
prop_path_diffracted.source = S; prop_path_diffracted.receiver = L;
prop_path_diffracted.receiver = L; prop_path_diffracted.identifier = 'diffracted_path';
prop_path_diffracted.identifier = 'diffracted_path'; prop_path_diffracted.delete = false;
prop_path_diffracted.delete = false; prop_path_diffracted.position = apex;
prop_path_diffracted.position = apex; prop_path_diffracted.delay = detour / c;
prop_path_diffracted.delay = detour / c; prop_path_diffracted.frequencies = f;
prop_path_diffracted.frequencies = f; prop_path_diffracted.gain = A / rho;
prop_path_diffracted.gain = A / rho; prop_path_diffracted.frequency_magnitudes = abs( D );
prop_path_diffracted.frequency_magnitudes = abs( D ); prop_path_diffracted.audible = true;
prop_path_diffracted.audible = true;
%% Reflected sound path
%% Reflected sound path
reflection_zone = ita_diffraction_reflection_zone( w, source_pos, receiver_pos, true );
reflection_zone = ita_diffraction_reflection_zone( w, source_pos, receiver_pos, true ); if n > 1 && last_reflection_zone ~= reflection_zone
if n > 1 && last_reflection_zone ~= reflection_zone fprintf( 'Reflection zone boundary has been crossed on frame %i (time %.2f)\n', n, n * timestep )
fprintf( 'Reflection zone boundary has been crossed on frame %i (time %.2f)\n', n, n * timestep ) end
end last_reflection_zone = reflection_zone;
last_reflection_zone = reflection_zone;
distance_source_main_face = dot( w.main_face_normal, source_pos - w.location );
distance_source_main_face = dot( w.main_face_normal, source_pos - w.location ); assert( ~reflection_zone || distance_source_main_face >= 0 )
assert( ~reflection_zone || distance_source_main_face >= 0 )
source_pos_image = source_pos - 2 * w.main_face_normal * distance_source_main_face;
source_pos_image = source_pos - 2 * w.main_face_normal * distance_source_main_face;
distance_image = norm( source_pos_image - receiver_pos );
distance_image = norm( source_pos_image - receiver_pos );
prop_path_reflected = struct();
prop_path_reflected = struct(); prop_path_reflected.identifier = 'reflected_path';
prop_path_reflected.identifier = 'reflected_path'; prop_path_reflected.gain = 1 / distance_image;
prop_path_reflected.gain = 1 / distance_image; prop_path_reflected.delay = distance_image / c; %delay from sound emitting from source to being received at listener
prop_path_reflected.delay = distance_image / c; %delay from sound emitting from source to being received at listener prop_path_reflected.frequencies = f; %Frequencies corresponding to the mags
prop_path_reflected.frequencies = f; %Frequencies corresponding to the mags values = ones(1,31);
values = ones(1,31); prop_path_reflected.frequency_magnitudes = values;
prop_path_reflected.frequency_magnitudes = values; prop_path_reflected.source = S; %sound source ID
prop_path_reflected.source = S; %sound source ID prop_path_reflected.receiver = L; %sound receiver ID
prop_path_reflected.receiver = L; %sound receiver ID prop_path_reflected.delete = false; %set to true when an existing path should be deleted
prop_path_reflected.delete = false; %set to true when an existing path should be deleted prop_path_reflected.position = source_pos_image;
prop_path_reflected.position = source_pos_image; prop_path_reflected.audible = reflection_zone; % Reflected field: may be inaudible
prop_path_reflected.audible = reflection_zone; % Reflected field: may be inaudible
R = 1;
R = 1; H_reflected = R ./ distance_image .* exp( -1i .* k ./ distance_image );
H_reflected = R ./ distance_image .* exp( -1i .* k ./ distance_image );
%% Update wave fronts in renderer
%% Update wave fronts in renderer paths_update = struct();
paths_update = struct(); if free_field_only || direct_field_component
if direct_field_component || direct_field_only paths_update.direct_path = prop_path_direct;
paths_update.direct_path = prop_path_direct; end
end if ~free_field_only && diffracted_field_component
if ~direct_field_only && diffracted_field_component paths_update.diffracted_path = prop_path_diffracted;
paths_update.diffracted_path = prop_path_diffracted; end
end if ~free_field_only && reflected_field_component
if ~direct_field_only && reflected_field_component paths_update.reflected_path = prop_path_reflected;
paths_update.reflected_path = prop_path_reflected; end
end
if ~dry_run
if ~dry_run
rends = va.get_rendering_modules();
rends = va.get_rendering_modules(); for rend_idx = 1:numel( rends )
for rend_idx = 1:numel( rends ) if strcmpi( rends( rend_idx ).class, 'BinauralOutdoorNoise' )
if strcmpi( rends( rend_idx ).class, 'BinauralOutdoorNoise' ) va.set_rendering_module_parameters( rends( rend_idx ).id, paths_update );
va.set_rendering_module_parameters( rends( rend_idx ).id, paths_update ); end
end end
end
% Increment core clock
% Increment core clock manual_clock = manual_clock + timestep;
manual_clock = manual_clock + timestep; va.call_module( 'manualclock', struct( 'time', manual_clock ) );
va.call_module( 'manualclock', struct( 'time', manual_clock ) );
% Process audio chain by incrementing one block
% Process audio chain by incrementing one block va.call_module( 'virtualaudiodevice', struct( 'trigger', true ) );
va.call_module( 'virtualaudiodevice', struct( 'trigger', true ) );
end
end
waitbar( n / numsteps )
waitbar( n / numsteps )
H_direct_log = [ H_direct_log; H_direct ];
H_direct_log = [ H_direct_log; H_direct ]; H_diffracted_log = [ H_diffracted_log; H_diffracted ];
H_diffracted_log = [ H_diffracted_log; H_diffracted ]; H_reflected_log = [ H_reflected_log; H_reflected ];
H_reflected_log = [ H_reflected_log; H_reflected ];
if shadow_zone
if shadow_zone H_total_field = H_diffracted;
H_total_field = H_diffracted; else
else if reflection_zone
if reflection_zone H_total_field = H_reflected + H_diffracted + H_direct;
H_total_field = H_reflected + H_diffracted + H_direct; else
else H_total_field = H_diffracted + H_direct;
H_total_field = H_diffracted + H_direct; end
end end
end
H_total_field_log = [ H_total_field_log; H_total_field ];
H_total_field_log = [ H_total_field_log; H_total_field ]; IL_log = [ IL_log; H_total_field ./ H_direct ];
IL_log = [ IL_log; H_total_field ./ H_direct ];
end
end close( h )
close( h )
if ~dry_run
if ~dry_run va.disconnect
va.disconnect disp( 'Stop VA to export simulation results from rendering module(s)' )
disp( 'Stop VA to export simulation results from rendering module(s)' ) else
else figure
figure plot( db( IL_log ) )
plot( db( IL_log ) ) end
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