Aufgrund einer Wartung wird GitLab am 18.01. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 18.01. between 8:00 and 9:00 am.

VA_example_ppa.m 11.7 KB
Newer Older
1
2
3
4
5
6
7
8
%% VA offline simulation/auralization example for outputs of the propagation path algorithm

% 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.

% Requires ITA-Toolbox, obtain from http://www.ita-toolbox.org

Dipl.-Ing. Jonas Stienen's avatar
WIP    
Dipl.-Ing. Jonas Stienen committed
9
output_folder = 'example_ppa_out';
10
frame_rate = 128 / 44100; % block length / sampling frequency
11

Dipl.-Ing. Jonas Stienen's avatar
WIP    
Dipl.-Ing. Jonas Stienen committed
12
13
S = 1;
R = 1;
henryjandrew's avatar
henryjandrew committed
14

15
16
ppa_example_mode = questdlg( 'Please select', 'VA example ppa mode selection', ...
    'simulation', 'auralization', 'both', 'both');
17

18
19
20
21
22
23
24
25
26
27
28
29
switch ppa_example_mode
    case { 'simulation', 'both' }
        
        %% Prepare run data
        
        record_paths = true;
        ppa_diffraction_model = 'utd';
        
        ppa_folder = '../../../dist/win32-x64.vc12/bin/UrbanTrajectory';
        
        if ~exist( ppa_folder, 'dir' )
            ppa_folder = '../../../ITAGeometricalAcoustics/ITAPropagationPathSim/tests/CombinedModel/UrbanTrajectory';
30
        end
31
32
33
        
        if ~exist( ppa_folder, 'dir' )
            error( 'Could not find trajectory source folder "%s".', ppa_folder )
34
        end
35
        
36
37
38
39
40
41
42
43
44
45
        file_listing = dir( strcat( ppa_folder, '/*.json' ) );
        
        f = ita_ANSI_center_frequencies;
        c = 343;
        
        all_path_names = cell(1);
        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
        source_str = struct; %struct with fields of source ID's and data of source positions for each frame
        receiver_str = struct;
        all_paths_data = struct;
46
47
        
        
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
        N = numel( file_listing );
        disp( [ 'Simulation result duration: ' num2str( N * frame_rate ) ' s' ] )
        
        h = waitbar( 0, 'Hold on, running simulation of path data for each frame' );
        
        % Iterate over frames
        n_continue = 1;
        for n = n_continue:N %loop over frames
            all_path_name = [];
            path_number = 1;
            
            % 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 = struct containing the current time frame
            pps = ita_propagation_paths_add_identifiers( pps );
            
            if n == n_continue
                pps_new = pps;
                pps_del = [];
                pps_common = [];
            else
                [ pps_new, pps_del, pps_common ] = ita_propagation_paths_diff( pps_last, pps );
            end
            pps_last = pps;
            
            
            % Update source (first anchor)
            if isa( pps( 1 ).propagation_anchors, 'struct' )
                source_pos = pps( 1 ).propagation_anchors( 1 ).interaction_point(1:3); % OpenGL coordinates?! -> transform using
                receiver_pos = pps( 1 ).propagation_anchors( end ).interaction_point(1:3); % OpenGL coordinates?! -> transform using
            else
                source_pos = pps( 1 ).propagation_anchors{ 1 }.interaction_point(1:3); % OpenGL coordinates?! -> transform using
                receiver_pos = pps( 1 ).propagation_anchors{ end }.interaction_point(1:3); % OpenGL coordinates?! -> transform using
            end
            source_str.(strcat('source_',num2str(S))) = source_pos;
            receiver_str.(strcat('receiver_',num2str(R))) = receiver_pos;
            
            paths_update = struct();
            
            % Delete non-available paths
            for p = 1:numel( pps_del )
                pu = struct(); % Path update
                pu.source = S;
                pu.receiver = R;
                pu.identifier = pps_del( p ).identifier;
                pu.delete = true;
                paths_update.( strcat( 'path_', pu.identifier ) ) = pu;
            end
            
            for p = 1:numel( pps_new )
98
                
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
                pp = pps_new( p ); % Propagation path
                pu = struct(); % Path update
                
                % Assemble DSP settings (gain, delay & filter coefficients)
                pu.source = S;
                pu.receiver = R;
                pu.identifier = pp.identifier;
                
                path_count = path_count + 1;
                all_path_names{path_count} = pp.identifier;
                
                if( record_paths )
                    [ frequency_mags, gain, delay, valid_p, path_data ] = ita_propagation_path_get_data( pp, f, c, 'record_paths' );
                    all_paths_data.( strcat( 'path_', pu.identifier ) ) = path_data;
                else
                    [ frequency_mags, gain, delay, valid_p ] = ita_propagation_path_get_data( pp, f, c );
                end
                %{
Dipl.-Ing. Jonas Stienen's avatar
WIP    
Dipl.-Ing. Jonas Stienen committed
117
118
        if ~valid_p %catch for error in ita_propagation_path_get_data
            warning( 'Error in ita_propagation_path_get_data, found invalid path ''%s'', skipping', pp.identifier );
119
120
            continue
        end
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
                %}
                if valid_p
                    pu.gain = gain;
                    pu.frequency_magnitudes = abs(frequency_mags);
                end
                pu.frequencies = f;
                pu.delay = delay;
                if isa(pp.propagation_anchors, 'struct')
                    pu.position = pp.propagation_anchors( end-1 ).interaction_point( 1:3 ); % next to last anchor
                else
                    pu.position = pp.propagation_anchors{ end-1 }.interaction_point( 1:3 ); % next to last anchor
                end
                pu.delete = false;
                pu.audible = true;
                
                paths_update.( strcat( 'path_', pu.identifier ) ) = pu;
            end
            
            for p = 1:numel( pps_common )
                
                pp = pps_common( p ); % Propagation path
                pu = struct(); % Path update
                
                % Assemble DSP settings (gain, delay & filter coefficients)
                pu.source = S;
                pu.receiver = R;
                pu.identifier = pp.identifier;
                
                if( record_paths )
                    [ frequency_mags, gain, delay, valid_p, path_data ] = ita_propagation_path_get_data( pp, f, c, 'record_paths' );
                    all_paths_data.( strcat( 'path_', pu.identifier ) ) = path_data;
                else
                    [ frequency_mags, gain, delay, valid_p ] = ita_propagation_path_get_data( pp, f, c );
                end
                %{
        if ~valid_p %catch for error in ita_propagation_path_get_data
            warning( 'Error in ita_propagation_path_get_data, found invalid path ''%s'', skipping', pp.identifier );
            continue
159
        end
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
                %}
                if( valid_p )
                    pu.gain = gain;
                    pu.frequency_magnitudes = abs(frequency_mags);
                end
                pu.frequencies = f;
                pu.delay = delay;
                if isa(pp.propagation_anchors, 'struct')
                    pu.position = pp.propagation_anchors( end-1 ).interaction_point( 1:3 ); % next to last anchor
                else
                    pu.position = pp.propagation_anchors{ end-1 }.interaction_point( 1:3 ); % next to last anchor
                end
                pu.delete = false;
                pu.audible = true;
                
                paths_update.( strcat( 'path_', pu.identifier ) ) = pu;
            end
            
            file_name = sprintf( 'frame%04idata.mat', n );
            file_path = fullfile( output_folder, file_name );
            save( file_path, 'paths_update', 'source_str', 'receiver_str' ); %save current frame data
            if( record_paths )
                save( file_path, 'all_paths_data', '-append' );
            end
            
            waitbar( n / N )
186
        end
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
        
        close( h )
        save( 'example_ppa_out\example_ppa_output_data.mat', 'all_path_names' ); %save variables to file
        
        disp('Finished generating path data for every frame. Data is saved in struct "run_data".');
        
        
    case { 'auralization', 'both' }
        
        %% Run auralization
        
        % Load data
        
        file_listing = dir( strcat( output_folder, '/frame*data.mat' ) );
        N = numel( file_listing );
        fprintf( 'Found data on %i frames in folder ''%s''\n', N, output_folder )
        
        frame_datenums = zeros( N, 1 );
        for n=1:N
            frame_datenums( n ) = file_listing( n ).datenum;
207
        end
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
        [ ~, idx ] = sort( frame_datenums );
        
        load( 'example_ppa_out\example_ppa_output_data.mat', 'all_path_names' )
        load( 'example_ppa_out\example_ppa_output_data.mat', 'source_str' )
        load( 'example_ppa_out\example_ppa_output_data.mat', 'receiver_str' )
        
        
        % Set up VA scene
        
        va = VA;
        
        va.connect;
        dry_run = false;
        
        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( 'C:/dev/VA/VACore/data' );
        va.add_search_path( 'D:/Users/stienen/dev/VA/VACore/data' );
        va.add_search_path( 'C:\ITASoftware\Raven\RavenDatabase\SoundDatabase' );
        
        c = va.get_homogeneous_medium_sound_speed();
        
        R = va.create_sound_receiver( 'PPA_sensor' );
        H = va.create_directivity_from_file( 'ITA_Artificial_Head_5x5_44kHz_128.v17.ir.daff' );
        va.set_sound_receiver_directivity( R, H );
        
        S = va.create_sound_source( 'PPA_emitter' );
        %X = va.create_signal_source_buffer_from_file( 'WelcomeToVA.wav' );
        X = va.create_signal_source_buffer_from_file( 'LKW Leerlauf 2.wav' );
        
        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 )
        
        manual_clock = 0;
        va.set_core_clock( 0 );
        h = waitbar( 0, 'Hold on, running auralisation using generated data' );
        
        % Run auralization update loop
        for n = 1:N
            
            idx_current = idx( n );
Dipl.-Ing. Jonas Stienen's avatar
WiP    
Dipl.-Ing. Jonas Stienen committed
250
            load( fullfile( output_folder, file_listing( idx_current ).name ), '-mat' ); % makes paths_update available
251
252
253
254
255
256
257
258
259
260
261
262
            
            source_pos = source_str.(strcat('source_',num2str(S-1)));
            receiver_pos = receiver_str.(strcat('receiver_',num2str(R-1)));
            
            % Update all propagation paths
            source_pos_OpenGL = ita_matlab2openGL( source_pos( 1:3 ) );
            receiver_pos_OpenGL = ita_matlab2openGL( receiver_pos( 1:3 ) );
            
            % Update receiver (last anchor)
            va.set_sound_source_position( S, source_pos_OpenGL );
            va.set_sound_receiver_position( R, receiver_pos_OpenGL );
            
Dipl.-Ing. Jonas Stienen's avatar
WiP    
Dipl.-Ing. Jonas Stienen committed
263
264
265
266
267
            if isfield( paths_update, 'path_003ca6d3a74540310873574908219251' )
                va.set_rendering_module_parameters( 'MyBinauralOutdoorNoise', paths_update );
            else
                disp( 'not found, skipping update' )
            end
268
269
270
271
272
273
274
275
276
277
            
            % Increment core clock
            manual_clock = manual_clock + frame_rate;
            va.call_module( 'manualclock', struct( 'time', manual_clock ) );
            
            % Process audio chain by incrementing one block
            va.call_module( 'virtualaudiodevice', struct( 'trigger', true ) );
            
            waitbar( n / N )
            
278
        end
279
        
Dipl.-Ing. Jonas Stienen's avatar
WiP    
Dipl.-Ing. Jonas Stienen committed
280
281
        close( h )
        
282
283
284
285
        va.disconnect
        disp( 'Stop VA to export simulation results from rendering module(s)' )
        
end