itaRavenProject.m 274 KB
Newer Older
1
classdef itaRavenProject < handle
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    %RavenProject - The class for working with RAVEN.
    % This class allows you to create configurations of settings, to
    % run simulations and to retrieve the results.
    %
    % Using:
    %   rpf = itaRavenProject(raven_project_file)
    %
    % Public Properties:
    %   Enter this command to get the properties:
    %   >> properties itaRavenProject
    %
    % Public Methods:
    %   Enter this command to get the methods:
    %   >> methods itaRavenProject
    %
    %   Enter this command to get more info of method:
    %   >> help itaRavenProject/methodname
    %
    %
    %
22
    % Examples:
23
    %   rpf = itaRavenProject();
24
25
26
27
28
    %   rpf.SetModel('cave.ac');
    %   rpf.getEquationBasedReverbTime(); returns reverb time based on
    %                                     sabine equation
    %   rpf.run();                        run simulation
    %   rpf.getT30();                     get T30 based on simulation
29
    %   rpf.plotMaterialsAbsorption();    plots absorption coefficients
30
    %
31
32
    % Author:           Soenke Pelzer (spe@akustik.rwth-aachen.de)
    %                   Lukas Aspck (las@akustik.rwth-aachen.de)
33
    %
34
    % Version:        0.2
35
    % First release:  01.11.10
36
    % Last revision:  11.07.18
37
38
    % Copyright:      Institute of Technical Acoustics, RWTH Aachen University
    %
39
40
41
42
43
44
    
    % <ITA-Toolbox>
    % This file is part of the application Raven for the ITA-Toolbox. All rights reserved.
    % You can find the license for this m-file in the application folder.
    % </ITA-Toolbox>
    
45
46
47
48
49
    
    properties(Constant)
        
        % CONSTANTS
        freqLabel3rd = { '   20 Hz', '   25 Hz', '   31 Hz', '   40 Hz', '   50 Hz', '   63 Hz', '   80 Hz', '  100 Hz', '  125 Hz', '  160 Hz', '  200 Hz', ...
50
51
52
            '  250 Hz', '  315 Hz', '  400 Hz', '  500 Hz', '  630 Hz', '  800 Hz', '   1 kHz', '1.25 kHz', ' 1.6 kHz', '   2 kHz', ...
            ' 2.5 kHz', '3.15 kHz', '   4 kHz', '   5 kHz', ' 6.3 kHz', '   8 kHz', '  10 kHz', '12.5 kHz', '  16 kHz', '  20 kHz'};
        freqLabelOct = { '   31 Hz', '   63 Hz', '  125 Hz', '  250 Hz', '  500 Hz', '   1 kHz', '   2 kHz', '   4 kHz', '   8 kHz', '  16 kHz'};
53
54
55
56
57
58
59
        freqVector3rd = [20 25 31.5 40 50 63 80 100 125 160 200 250 315 400 500 630 800 1000 1250 1600 2000 2500 3150 4000 5000 6300 8000 10000 12500 16000 20000];
        freqVectorOct = [31.5 63 125 250 500 1000 2000 4000 8000 16000];
        MODE_BSP   = 0;
        MODE_HASH  = 1;
        MODE_BRUTE = 2;
        COORD_TRAFO_SKETCHUP2RAVEN = [1 3 -2];
        COORD_TRAFO_RAVEN2SKETCHUP = [1 -3 2];
60
    end
61
62
63
    
    properties (GetAccess = 'public', SetAccess = 'private')
        % raven
64
        
65
66
67
        ravenExe
        ravenLogFile = 'RavenLog.txt'
        ravenProjectFile
68
        ravenIniFile
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
        projectName
        
        % general
        sampleRate = 44100
        
        % paths
        pathResults
        pathDirectivities
        pathMaterials
        fileHRTF
        fileSpeakers
        
        % model
        modelFileList = []
        model = []
        
        % [Global]
        simulationTypeIS
        simulationTypeRT
        generateRIR
        generateBRIR
        generateISHOA
        generateRTHOA
        generateISVBAP
        generateRTVBAP
        exportFilter
        exportHistogram
        exportWallHitLog
        exportPlaneWaveList
        accelerationType
        logPerformance
        
        % [PrimarySources] %
        sourceNames
        sourceDirectivity
        sourcePositions
        sourceViewVectors
        sourceUpVectors
        sourceSoundStates
        sourceSoundLevels
        
        % [Receiver] %
        receiverNames
        receiverPositions
        receiverViewVectors
        receiverUpVectors
        receiverStates
        
        % [ImageSources] %
        ISOrder_PS
        ISOrder_SS
        ISSkipDirectSound
        
        % [RayTracing] %
        numParticles_Sphere
        numParticles_Portal
        energyLoss_Sphere
        energyLoss_Portal
127
128
        detectionSphereAziResolution
        detectionSphereEleResolution
129
130
131
132
133
134
135
136
137
        filterLength
        timeSlotLength
        radiusSphere
        fixReflectionPattern
        
        % [Filter] %
        fixPoissonSequence
        poissonSequenceNumber
        filterResolution
138
        maxReflectionDensity
139
140
141
142
        ambisonicsOrder
        numberSpreadedSources
        spreadingStdDeviation
        fftDegreeForWallFilterInterpolation
143
        
144
145
146
        % [PlaneWaveLists] %
        planeWaveList_IS = []
        planeWaveList_RT = []
147
        
148
149
150
151
152
        % [Performance]
        performance = struct('ISFilterMonaural',[],'ISFilterBinaural',[],'RTFilterMonaural',[],'RTFilterBinaural',[],'ISGenerateImageSources',[],'ISTransformationMatrix',[],'ISAudibilityTest',[],'RTTotal',[],'RTBands',[]);
        
    end
    
153
    properties (GetAccess = 'public', SetAccess = 'public')
154
155
156
157
158
        % [WallHitLogs] %
        wallHitLog_IS = []
        wallHitLog_RT = []
        initialParticleEnergy = []
    end
159
    
160
    properties (GetAccess = 'private', SetAccess = 'private')
161
162
163
164
        
        ravenExe64 = '..\bin64\RavenConsole64.exe'
        ravenExe32 = '..\bin32\RavenConsole.exe'
        
165
        rpf_ini
166
        raven_ini
167
168
169
170
171
172
173
        projectID
        projectTag
        
        projectLoaded = false
        simulationDone = false
        
        keepOutputFiles
174
        plotModelHandle = [];
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
        
        % [PrimarySources] %
        sourceNameString
        sourceDirectivityString
        
        % [Receiver] %
        receiverNameString
        uniformReceiverGridX = []
        uniformReceiverGridY = []
        uniformReceiverGridZ = []
        
        % RESULTS %
        monauralIR = []
        monauralIR_IS = []
        monauralIR_RT = []
        binauralIR = []
        binauralIR_IS = []
        binauralIR_RT = []
        ambisonicsIR = []
        ambisonicsIR_IS = []
        ambisonicsIR_RT = []
        vbapIR = []
        vbapIR_IS = []
        vbapIR_RT = []
        histogram = []
        histogramRT = []
    end
    
    
    %---------------------- PUBLIC METHODS -------------------------------%
    methods
        %------------------------------------------------------------------
207
        function obj = itaRavenProject(raven_project_file)
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
            %RavenProject - constructor
            % To Create a new project with empty default configuration.
            %
            % Using:
            %   rpf = RavenProject(raven_project_file)
            %
            % Input:
            %   [optional] existing raven project file
            %
            % Output:
            %   obj - an instance of class RavenProject
            %
            
            if strcmp(computer('arch'), 'win32')
                obj.ravenExe = obj.ravenExe32;
            elseif strcmp(computer('arch'), 'win64')
                obj.ravenExe = obj.ravenExe64;
            else
                error('Only Windows OS are supported.');
            end
            
229
230
231
232
233
234
            itaRavenProjectPath = which('itaRavenProject.m');
            obj.ravenIniFile = [ itaRavenProjectPath(1:end-9) '.ini'];
            
            ravenIniExists = exist(obj.ravenIniFile,'file');
            
            if (ravenIniExists)
235
236
237
238
                % load path from itaRaven.ini
                obj.raven_ini = IniConfig();
                obj.raven_ini.ReadFile(obj.ravenIniFile);
                obj.ravenExe         = obj.raven_ini.GetValues('Global', 'PathRavenExe', obj.ravenExe);
239
240
241
                if (exist(obj.ravenExe,'file'))
                    obj.raven_ini.WriteFile(obj.ravenIniFile);
                end
242
243
            end
            
244
            if (~exist(obj.ravenExe,'file'))
245
246
247
248
249
250
                
                % neither the default raven console or the path in
                % itaRaven.ini was not found, try to locate
                % RavenConsole
                locatedRavenExe = which(obj.ravenExe(10:end));
                
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
                % try default raven exe path after instalation
                if isempty(locatedRavenExe)
                    if strcmp(computer('arch'), 'win32')
                        defaultInstallationPathRavenExe = 'C:\ITASoftware\Raven\bin32\RavenConsole.exe';
                    elseif strcmp(computer('arch'), 'win64')
                        defaultInstallationPathRavenExe = 'C:\ITASoftware\Raven\bin64\RavenConsole64.exe';
                    else
                        error('Only Windows OS are supported.');
                    end
                    
                    if exist(defaultInstallationPathRavenExe,'file')
                        locatedRavenExe = defaultInstallationPathRavenExe;
                    end
                end
                
266
                if isempty(locatedRavenExe)
267
268
269
270
271
272
273
                    
                    disp('[itaRaven]:');
                    disp('No RAVEN binary was found! Please select path to the RAVEN console application (RavenConsole.exe/RavenConsole64.exe)!');
                    disp('To run RAVEN simulations, an installation of the RAVEN software is required. ');
                    disp('Individual licenses for academic purposes are available on request.');
                    disp('Please contact: las@akustik.rwth-aachen.de');
                    
274
275
276
277
                    [ selectedRavenExe, selectedRavenPath] = uigetfile('*.exe',' No raven binary was found! Please select path to RavenConsole.exe');
                    obj.ravenExe = [ selectedRavenPath selectedRavenExe];
                else
                    obj.ravenExe = locatedRavenExe;
278
                    
279
280
281
282
283
284
                end
                
                if (~ravenIniExists)
                    obj.raven_ini = IniConfig();
                    obj.raven_ini.AddSections({'Global'});
                    obj.raven_ini.AddKeys('Global', {'PathRavenExe'}, {obj.ravenExe});
285
286
                    obj.raven_ini.WriteFile(obj.ravenIniFile);
                    
287
288
                else
                    obj.raven_ini.SetValues('Global', {'PathRavenExe'}, {obj.ravenExe});
289
                    obj.raven_ini.WriteFile(obj.ravenIniFile);
290
291
                end
                
292
            end
293
            
294
            % check if raven project file exists
295
296
297
298
299
300
301
            if (nargin > 0) && exist(raven_project_file, 'file')
                obj.loadRavenConfig(raven_project_file);
            else
                error('No raven project file given or file not found.');
            end
        end
        
302
303
304
305
        function delete(obj)
            obj.deleteResultsInRavenFolder();
        end
        
306
307
        
        %------------------------------------------------------------------
308
        function copyProjectToNewRPFFile(obj, newPath)
309
310
311
312
313
314
315
316
317
            if (exist(fileparts(newPath),'dir'))
                obj.ravenProjectFile = newPath;
                obj.rpf_ini.WriteFile(obj.ravenProjectFile);
            else
                error('itaRavenProject/copyProjectToNewRPFFile: invalid path');
            end
        end
        
        
318
319
        %------------------------------------------------------------------
        function setRavenExe(obj, newRavenExe)
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
            
            
            if (exist(newRavenExe,'file'))
                
                obj.ravenExe = newRavenExe;
                
                if (exist(obj.ravenIniFile,'file'))
                    obj.raven_ini.SetValues('Global', {'PathRavenExe'}, {obj.ravenExe});
                    obj.raven_ini.WriteFile(obj.ravenIniFile);
                else
                    obj.raven_ini = IniConfig();
                    obj.raven_ini.AddSections({'Global'});
                    obj.raven_ini.AddKeys('Global', {'PathRavenExe'}, {obj.ravenExe});
                end
                
335
            else
336
337
                error('[itaRaven]: Error: Path to new Raven binary not found!');
                
338
            end
339
            
340
341
342
343
344
345
346
        end
        
        %------------------------------------------------------------------
        function loadRavenConfig(obj, filename)
            %loadRavenConfig - Reads an existing raven project file
            %
            
347
348
349
350
351
352
            % change relative to absolute path
            if (~strcmp(filename(2),':'))
                obj.ravenProjectFile = [pwd '\' filename];
            else
                obj.ravenProjectFile = filename;
            end
353
354
355
356
357
358
            
            obj.rpf_ini = IniConfig();
            obj.rpf_ini.ReadFile(filename);
            
            % [Global] %
            obj.projectName         = obj.rpf_ini.GetValues('Global', 'ProjectName', 'Matlab');
359
            obj.projectTag          = obj.projectName;
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
            obj.pathResults         = obj.rpf_ini.GetValues('Global', 'ProjectPath_Output', '..\RavenOutput');
            obj.pathDirectivities   = obj.rpf_ini.GetValues('Global', 'ProjectPath_DirectivityDB', '..\RavenDatabase\DirectivityDatabase');
            obj.pathMaterials       = obj.rpf_ini.GetValues('Global', 'ProjectPath_MaterialDB', '..\RavenDatabase\MaterialDatabase');
            obj.fileHRTF            = obj.rpf_ini.GetValues('Global', 'ProjectPath_HRTFDB', '..\RavenDatabase\HRTF\ITA-Kunstkopf_HRIR_AP11_Pressure_Equalized_3x3_256.daff');
            obj.fileSpeakers        = obj.rpf_ini.GetValues('Global', 'SpeakerConfigFile', 'Speakers.ini');
            obj.simulationTypeIS    = obj.rpf_ini.GetValues('Global', 'simulationTypeIS', 1);
            obj.simulationTypeRT    = obj.rpf_ini.GetValues('Global', 'simulationTypeRT', 1);
            obj.generateRIR         = obj.rpf_ini.GetValues('Global', 'generateRIR', 1);
            obj.generateBRIR        = obj.rpf_ini.GetValues('Global', 'generateBRIR', 1);
            obj.generateISHOA       = obj.rpf_ini.GetValues('Global', 'generateISHOA', 0);
            obj.generateRTHOA       = obj.rpf_ini.GetValues('Global', 'generateRTHOA', 0);
            obj.generateISVBAP      = obj.rpf_ini.GetValues('Global', 'generateISVBAP', 0);
            obj.generateRTVBAP      = obj.rpf_ini.GetValues('Global', 'generateRTVBAP', 0);
            obj.exportFilter        = obj.rpf_ini.GetValues('Global', 'exportFilter', 1);
            obj.exportHistogram     = obj.rpf_ini.GetValues('Global', 'exportHistogram', 1);
            obj.exportWallHitLog    = obj.rpf_ini.GetValues('Global', 'exportWallHitList', 0);
            obj.exportPlaneWaveList = obj.rpf_ini.GetValues('Global', 'exportPlaneWaveList', 0);
            obj.accelerationType    = obj.rpf_ini.GetValues('Global', 'accelerationType', 0);   % default 0 = MODE_BSP
            obj.logPerformance      = obj.rpf_ini.GetValues('Global', 'logPerformance', 0);
            obj.keepOutputFiles     = obj.rpf_ini.GetValues('Global', 'keepOutputFiles', 0);
            
381
            
382
383
384
385
386
387
388
            % change relative to absolute paths
            if obj.ravenExe(2) == ':' % absolute path
                ravenBasePath = fileparts(fileparts(obj.ravenExe)); % base path of raven
                
                if (strcmp(obj.pathResults(1:2),'..')), obj.pathResults = [ ravenBasePath obj.pathResults(3:end) ]; end
                if (strcmp(obj.pathDirectivities(1:2),'..')), obj.pathDirectivities = [ ravenBasePath obj.pathDirectivities(3:end) ]; end
                if (strcmp(obj.pathMaterials(1:2),'..')), obj.pathMaterials = [ ravenBasePath obj.pathMaterials(3:end) ]; end
389
390
                if (strcmp(obj.fileHRTF(1:2),'..')), obj.fileHRTF = [ ravenBasePath obj.fileHRTF(3:end) ]; end
                
391
                
392
393
            end
            
394
395
396
397
398
399
            % [Rooms] %
            model_string            = obj.rpf_ini.GetValues('Rooms',  'Model');
            obj.modelFileList       = textscan(model_string, '%s', 'Delimiter' , ',');
            obj.modelFileList       = obj.modelFileList{1}; % textscan implementation issue
            if numel(obj.modelFileList) == 1
                obj.modelFileList = obj.modelFileList{1};   % de-cell if only 1 room given
400
401
                
                if obj.ravenExe(2) == ':' % convert to absolute path
402
                    if (strcmp(obj.modelFileList(1:2),'..')), obj.modelFileList = [ ravenBasePath obj.modelFileList(3:end) ]; end
403
                end
404
405
            end
            
406
407
            
            
408
            
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
            % [PrimarySources] %
            obj.sourceNameString    = obj.rpf_ini.GetValues('PrimarySources', 'sourceNames', 'Sender');
            obj.sourceNames         = textscan(obj.sourceNameString, '%s', 'Delimiter', ',');
            obj.sourceNames         = obj.sourceNames{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            obj.sourceDirectivityString = obj.rpf_ini.GetValues('PrimarySources', 'sourceDirectivity', '');
            if ~isempty(obj.sourceDirectivityString)
                obj.sourceDirectivity   = textscan(obj.sourceDirectivityString, '%s', 'Delimiter', ',');
                obj.sourceDirectivity   = obj.sourceDirectivity{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            else
                obj.sourceDirectivity   = {};
            end
            obj.sourcePositions     = obj.rpf_ini.GetValues('PrimarySources', 'sourcePositions');
            obj.sourcePositions     = reshape(obj.sourcePositions, 3, numel(obj.sourcePositions)/3)';
            obj.sourceViewVectors   = obj.rpf_ini.GetValues('PrimarySources', 'sourceViewVectors', '0, 0, 1');
            obj.sourceViewVectors   = reshape(obj.sourceViewVectors, 3, numel(obj.sourceViewVectors)/3)';
            obj.sourceUpVectors     = obj.rpf_ini.GetValues('PrimarySources', 'sourceUpVectors', '0, 1, 0');
            obj.sourceUpVectors     = reshape(obj.sourceUpVectors, 3, numel(obj.sourceUpVectors)/3)';
            obj.sourceSoundStates   = obj.rpf_ini.GetValues('PrimarySources', 'sourceSoundStates', '1');
            obj.sourceSoundLevels   = obj.rpf_ini.GetValues('PrimarySources', 'sourceSoundLevels', '100');
            
            % [Receiver] %
            obj.receiverNameString  = obj.rpf_ini.GetValues('Receiver', 'receiverNames', 'Receiver');
            obj.receiverNames       = textscan(obj.receiverNameString, '%s', 'Delimiter', ',');
            obj.receiverNames       = obj.receiverNames{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            obj.receiverPositions   = obj.rpf_ini.GetValues('Receiver', 'receiverPositions');
            obj.receiverPositions   = reshape(obj.receiverPositions, 3, numel(obj.receiverPositions)/3)';
            obj.receiverViewVectors = obj.rpf_ini.GetValues('Receiver', 'receiverViewVectors', '1, 0 ,0');
            obj.receiverViewVectors = reshape(obj.receiverViewVectors, 3, numel(obj.receiverViewVectors)/3)';
            obj.receiverUpVectors   = obj.rpf_ini.GetValues('Receiver', 'receiverUpVectors', '0, 1, 0');
            obj.receiverUpVectors   = reshape(obj.receiverUpVectors, 3, numel(obj.receiverUpVectors)/3)';
            
            % [ImageSources] %
            obj.ISOrder_PS          = obj.rpf_ini.GetValues('ImageSources', 'ISOrder_PS', 2);
            obj.ISOrder_SS          = obj.rpf_ini.GetValues('ImageSources', 'ISOrder_SS', 2);
            obj.ISSkipDirectSound   = obj.rpf_ini.GetValues('ImageSources', 'ISSkipDirectSound', 0);
            
            % [RayTracing] %
            obj.numParticles_Sphere = obj.rpf_ini.GetValues('RayTracing', 'numberOfParticles_DetectionSphere', 10000);
            obj.numParticles_Portal = obj.rpf_ini.GetValues('RayTracing', 'numberOfParticles_Portal', 10000);
            obj.energyLoss_Sphere   = obj.rpf_ini.GetValues('RayTracing', 'energyLoss_DetectionSphere', 63);
            obj.energyLoss_Portal   = obj.rpf_ini.GetValues('RayTracing', 'energyLoss_Portal', 63);
            obj.filterLength        = obj.rpf_ini.GetValues('RayTracing', 'filterLength_DetectionSphere', 2000);
            obj.timeSlotLength      = obj.rpf_ini.GetValues('RayTracing', 'timeResolution_DetectionSphere', 6);
            obj.radiusSphere        = obj.rpf_ini.GetValues('RayTracing', 'radius_DetectionSphere', 0.5);
            obj.fixReflectionPattern= obj.rpf_ini.GetValues('RayTracing', 'fixReflectionPattern', 0);
            
            % [Filter] %
            obj.fixPoissonSequence  = obj.rpf_ini.GetValues('Filter', 'setFixPoissonSequence', 0);
            obj.poissonSequenceNumber = obj.rpf_ini.GetValues('Filter', 'poissonSequenceNumber', 9876);
            obj.filterResolution    = obj.rpf_ini.GetValues('Filter', 'filterResolution', 1);   % 1 = Octave, 0 = 3rd Octave
            obj.ambisonicsOrder     = obj.rpf_ini.GetValues('Filter', 'ambisonicsOrder', -1);
            obj.numberSpreadedSources             = obj.rpf_ini.GetValues('Filter', 'numberSpreadedSources', 0);
            obj.spreadingStdDeviation             = obj.rpf_ini.GetValues('Filter', 'spreadingStdDeviation', 0.2);
            obj.fftDegreeForWallFilterInterpolation = obj.rpf_ini.GetValues('Filter', 'fftDegreeForWallFilterInterpolation', 8);
            
            obj.projectLoaded = true;
        end
        
        %------------------------------------------------------------------
        function reloadRavenConfig(obj, filename)
            if nargin < 2
                filename = obj.ravenProjectFile;
            end
            
            obj.loadRavenConfig(filename);
        end
        
476
        %------------------------------------------------------------------
477
478
479
480
481
482
        function saveRavenConfig(obj, filename)
            %saveRavenConfig - Saves the current object in a (different)
            %raven project file. Can be used as a log if various
            %simulations are run with multiple configurations
            %
            obj.rpf_ini.WriteFile(filename);
483
            
484
485
        end
        
486
487
        %------------------------------------------------------------------
        function run(obj)
Philipp Schäfer's avatar
Philipp Schäfer committed
488
489
490
            if numel(obj.projectName) > 70
                warning('Long project name. This might cause an error while writing output files. Consider resetting your project name!')
            end
491
492
493
494
495
496
497
498
499
500
501
            
            obj.simulationDone = false;
            
            if obj.projectLoaded
                savedProjectName = obj.projectName;
                
                obj.projectID = datestr(now, 30);
                obj.projectTag = [obj.projectName obj.projectID];
                
                % give the project name a date and time string to help to identify the results
                obj.setProjectName(obj.projectTag);
502
                
503
504
505
506
507
508
                % run the simulation
                disp(['Running simulation... (' obj.ravenExe ')']);
                if exist(obj.ravenLogFile, 'file')
                    delete(obj.ravenLogFile);
                end
                %                 system([obj.ravenExe ' "' obj.ravenProjectFile '" >> ' obj.ravenLogFile]);
509
510
511
512
513
                
                if (~exist(obj.ravenExe,'file'))
                    error('[itaRaven]: Error: Cannot find Raven binary file!');
                end
                
514
515
                prevPath = pwd;
                cd(fileparts(obj.ravenExe));
516
                dos(['"' obj.ravenExe '"' ' "' obj.ravenProjectFile '"'],'-echo');
517
                cd(prevPath);
518
519
520
521
522
                
                % restore the initial project name
                obj.setProjectName(savedProjectName);
                
                % gather results
523
                disp('[R] Simulation seems to be finished. Getting results...');
524
                obj.gatherResults();
525
                disp('[R] Done.');
526
527
528
529
530
531
532
533
534
535
536
537
538
                
                obj.simulationDone = true;
                
                % delete results in raven folder structure -> they are copied now into this class
                if (obj.keepOutputFiles == 0)
                    obj.deleteResultsInRavenFolder();
                end
            else
                disp('No projected defined yet.');
            end
            
        end
        
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
        %------------------------------------------------------------------
        function runNoGathering(obj)
            % basicly the same as the run method, but without the call of
            % obj.gatherResults();
            
            obj.simulationDone = false;
            
            if obj.projectLoaded
                savedProjectName = obj.projectName;
                
                obj.projectID = datestr(now, 30);
                obj.projectTag = [obj.projectName obj.projectID];
                
                % give the project name a date and time string to help to identify the results
                obj.setProjectName(obj.projectTag);
                
                % set filter length to the length of the reverberation
                %                 obj.setFilterLengthToReverbTime();
                
                % run the simulation
                disp(['Running simulation... (' obj.ravenExe ')']);
                if exist(obj.ravenLogFile, 'file')
                    delete(obj.ravenLogFile);
                end
                %                 system([obj.ravenExe ' "' obj.ravenProjectFile '" >> ' obj.ravenLogFile]);
564
565
566
                prevPath = pwd;
                cd(fileparts(obj.ravenExe));
                dos(['"' obj.ravenExe '"' ' "' obj.ravenProjectFile '"'],'-echo');
567
                disp('Done.');
568
569
                cd(prevPath);
                
570
571
572
573
574
575
                
                % restore the initial project name
                obj.setProjectName(savedProjectName);
                
                % gather results
                disp('This function does _not_ gather the results. Please provide arguments to getWallHitLogBand(band)');
576
577
                %                 obj.gatherResults();
                %                 disp('Done.');
578
579
580
581
                
                obj.simulationDone = true;
                
                % delete results in raven folder structure -> they are copied now into this class
582
583
584
                %                 if (obj.keepOutputFiles == 0)
                %                     obj.deleteResultsInRavenFolder();
                %                 end
585
586
587
588
589
590
            else
                disp('No projected defined yet.');
            end
            
        end
        
591
592
593
594
        %------------------------------------------------------------------
        function keepImpulseResponseFiles(obj, keepFiles)
            % keepImpulseResponseFiles
            %
595
            %   By default, RAVEN Impulse Responses are deleted from the hard disk
596
597
598
599
600
601
602
603
            %   after simulation and are only available in your rpf project
            %
            %   By setting keepOutFiles to 1 / true, results are kept in
            %   the Output-Folder (obj.pathResults)
            
            obj.keepOutputFiles     = keepFiles;
            obj.rpf_ini.SetValues('Global', 'keepOutputFiles', keepFiles);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
604
        end
605
        
606
        %------------------------------------------------------------------
607
608
        function openOutputFolder(obj)
            % opens the output folder in windows explorer
609
            
610
611
612
613
614
615
616
617
618
            if (exist(obj.pathResults,'dir'))
                dos(['C:\Windows\Explorer.exe ' obj.pathResults]);
            else
                disp('Output Folder does not exist!');
            end
            
        end
        
        
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
        %------------------------------------------------------------------
        function numReceivers = createReceiverArray(obj, xpositions, zpositions, yheight)
            numReceivers = numel(xpositions) * numel(zpositions);
            [obj.uniformReceiverGridX, obj.uniformReceiverGridZ] = meshgrid(xpositions, zpositions);
            obj.uniformReceiverGridY = ones(size(obj.uniformReceiverGridX,1), size(obj.uniformReceiverGridX,2)) * yheight;
            
            rec_names = obj.makeNumberedNames('Array', numReceivers);
            rec_states = str2num(obj.writeXtimes_num(1, numReceivers));
            rec_view = str2num(obj.writeXtimes('1,0,0', numReceivers));
            rec_up = str2num(obj.writeXtimes('0,1,0', numReceivers));
            
            positions = zeros(numReceivers * 3, 1);
            positions(1:3:end) = obj.uniformReceiverGridX(:);
            positions(2:3:end) = obj.uniformReceiverGridY(:);
            positions(3:3:end) = obj.uniformReceiverGridZ(:);
            
            obj.setReceiverNames(rec_names);
            obj.setReceiverPositions(positions);
            obj.setReceiverViewVectors(rec_view);
            obj.setReceiverUpVectors(rec_up);
            obj.setReceiverStates(rec_states);
            
            disp(['Receiver grid created successfully. ' num2str(numReceivers) ' receivers placed.']);
        end
        
        %------------------------------------------------------------------
        function createReceiverArrayAuto(obj, yheight, distance, roomID)
            
            if nargin < 4
                roomID = 0;   % default = first room (ID = 0)
            end
            
            if isempty(obj.model)
                if iscell(obj.modelFileList)
                    for iRoom = 1 : numel(obj.modelFileList)
654
                        obj.model{iRoom} = itaAc3dModel(obj.modelFileList{iRoom});
655
656
657
                    end
                    roommodel = obj.model{roomID + 1};
                else
658
                    obj.model = itaAc3dModel(obj.modelFileList);
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
                    roommodel = obj.model;
                end
            else
                if iscell(obj.model)
                    roommodel = obj.model{roomID + 1};
                else
                    roommodel = obj.model;
                end
            end
            
            if nargin < 3
                distance = 1;   % default = 1 meter
            end
            
            if nargin < 2
                yheight = min(roommodel.nodes(:,2)) + 1.2;  % default listener 1.2 meters above ground
                if yheight > max(roommodel.nodes(:,2))
                    yheight = mean(roommodel.nodes(:,2));   % if 1.2 meters is out of ceiling, try putting receivers in the middle between floor and ceiling
                end
            end
            
            xpositions = min(roommodel.nodes(:,1)) + distance/2 : distance : max(roommodel.nodes(:,1)) - distance/2;
            zpositions = min(roommodel.nodes(:,3)) + distance/2 : distance : max(roommodel.nodes(:,3)) - distance/2;
            
            obj.createReceiverArray(xpositions, zpositions, yheight);
        end
        
        %------------------------------------------------------------------
        function rebuildReceiverGrid(obj)
            numReceivers = numel(obj.receiverPositions) / 3;    %xyz
            if numReceivers < 1
                error('No receiver position data present.');
            end
            x = obj.receiverPositions(:,1);
            y = obj.receiverPositions(:,2);
            z = obj.receiverPositions(:,3);
            averageDistance = sqrt((max(x)-min(x))*(max(z)-min(z)) / numReceivers);
            obj.createReceiverArray(min(x) : averageDistance : max(x), min(z) : averageDistance : max(z), mean(y));
        end
        
        %------------------------------------------------------------------
        function setModel(obj, filename)
            
            if (nargin < 2)
                error('Not enough input arguments.')
            end
            
            if ~ischar(filename)
                error('Requires string input.')
            else
                if iscell(filename)
                    obj.modelFileList = obj.cat_cell_of_strings(filename);
                else
                    obj.modelFileList = filename;
                end
                obj.rpf_ini.SetValues('Rooms', 'Model', obj.modelFileList);
            end
            
            obj.model = [];
            
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
        %------------------------------------------------------------------
        function [outputFilePath] = setModelToShoebox(obj, length,width,height)
            % setModelToShoebox
            % creates a shoebox room model and automatically sets the model
            % of the current project to the defined shoebox room.
            % The shoebox room has 6 materials assigned (matShoebox1 ..
            % matShoebox6), which can be set using
            %       rpf.setMaterial(matShoebox1,abs,scat)
            %
            % surface order:
            % (1) floor, (2) ceiling,
            % (3) larger wall (length x height; left, view from origin)
            % (4) smaller wall (width x height; front)
            % (5) larger wall (length x height; right)
            % (6) smaller wall (width x height; back)
            
            % Using:
            %   outputFileName = rpf.setModelToShoebox(myLength,myWidth,myHeight);
            %
            %   see ita_raven_demo_shoebox for more details on usage
            %
            % Input:
            %   length, width, height (all in meters)
            %
            % Output:
            %   outputFilePath: full path of save ac3d model
            %
            
            outputFileName = ['Shoebox_' num2str(length) 'x' num2str(width) 'x' num2str(height) '.ac' ];
            
            if strfind(obj.modelFileList,'RavenModels')
                outputFilePath = [ obj.modelFileList(1:strfind(obj.modelFileList,'RavenModels')+10) '\' outputFileName ];
                
            else
                % if model wasn't stored in RavenModels folder, save it in
                % the folder of the current rpf file.
                outputFilePath = [ fileparts(obj.ravenProjectFile) '\' outputFileName ];
            end
            
            fid = fopen(outputFilePath,'w');
            fprintf(fid,'AC3Db\n');
            for iMat=1:6
                fprintf(fid,['MATERIAL "matShoebox' num2str(iMat) '" rgb ' num2str(0.0) ' ' num2str(0.0) ' ' num2str(0.1*iMat) ' amb 0.2 0.2 0.2  emis 0 0 0  spec 0.2 0.2 0.2  shi 128  trans 0 \n']);
            end
            
            fprintf(fid,'OBJECT world\n');
            fprintf(fid,'kids 6\n');
            
            lS=sprintf('%1.4f',length);
            wS=sprintf('%1.4f',-width);
            hS=sprintf('%1.4f',height);
            
            for iWall=1:6
                fprintf(fid,'OBJECT poly\n');
                fprintf(fid,'name "polygon_object"\n');
                fprintf(fid,'numvert 4\n');
                
                if iWall==1
                    fprintf(fid,'0 0 0\n');
                    fprintf(fid,[lS ' 0 0\n']);
                    fprintf(fid,[lS ' 0 ' wS '\n']);
                    fprintf(fid,['0 0 ' wS '\n']);
                end
                
                if iWall==2
                    fprintf(fid,[lS ' ' hS ' 0\n']);
                    fprintf(fid,['0 ' hS ' 0\n']);
                    fprintf(fid,['0 ' hS ' '  wS '\n']);
                    fprintf(fid,[lS ' ' hS ' '  wS '\n']);
                end
                
                if iWall==3
                    fprintf(fid,[lS ' 0 0\n']);
                    fprintf(fid,'0 0 0\n');
                    fprintf(fid,['0 ' hS ' 0\n']);
                    fprintf(fid,[lS ' ' hS ' 0\n']);
                end
                
                if iWall==4
                    fprintf(fid,'0 0 0\n');
                    fprintf(fid,['0 0 ' wS '\n']);
                    fprintf(fid,['0 ' hS ' '  wS '\n']);
                    fprintf(fid,['0 ' hS ' 0\n']);
                end
                
                if iWall==5
                    fprintf(fid,['0 0 ' wS '\n']);
                    fprintf(fid,[lS ' 0 ' wS '\n']);
                    fprintf(fid,[lS ' ' hS ' '  wS '\n']);
                    fprintf(fid,['0 ' hS ' '  wS '\n']);
                end
                
                if iWall==6
                    fprintf(fid,[lS ' 0 ' wS '\n']);
                    fprintf(fid,[lS ' 0 0\n']);
                    fprintf(fid,[lS ' ' hS ' 0\n']);
                    fprintf(fid,[lS ' ' hS ' '  wS '\n']);
                end
                
                fprintf(fid,'numsurf 1\n');
                fprintf(fid,'SURF 0x10\n');
                fprintf(fid,['mat ' num2str(iWall-1) '\n']);
                fprintf(fid,'refs 4\n');
                fprintf(fid,'3 0 0\n');
                fprintf(fid,'2 0 0\n');
                fprintf(fid,'1 0 0\n');
                fprintf(fid,'0 0 0\n');
                fprintf(fid,'kids 0\n');
                
                
            end
            
            fclose(fid);
            obj.setModel(outputFilePath);
            
        end
        
839
840
841
842
843
844
845
846
847
848
849
850
851
852
        %------------------------------------------------------------------
        function plotModel(obj, tgtAxes, comp2axesMapping, wireframe)
            if isempty(obj.modelFileList)
                return;
            end
            
            if nargin < 4
                wireframe = 0;
            else
                if ischar(wireframe)
                    wireframe = isequal(wireframe, 'wireframe');
                end
            end
            if nargin < 3
Philipp Schäfer's avatar
Philipp Schäfer committed
853
                comp2axesMapping = [1 -3 2];
854
855
            end
            if nargin < 2
856
857
858
859
860
861
862
                if (ishandle(obj.plotModelHandle))
                    tgtAxes = obj.plotModelHandle;
                else
                    figure;
                    tgtAxes = gca;
                end
                
863
864
            end
            
865
866
            obj.plotModelHandle = tgtAxes;
            
867
868
869
            if isempty(obj.model)
                if iscell(obj.modelFileList)
                    for iRoom = 1 : numel(obj.modelFileList)
870
                        obj.model{iRoom} = itaAc3dModel(obj.modelFileList{iRoom});
871
872
873
874
                        obj.model{iRoom}.plotModel(tgtAxes, comp2axesMapping, wireframe);
                        hold on;
                    end
                else
875
                    obj.model = itaAc3dModel(obj.modelFileList);
876
877
878
879
880
881
882
883
884
885
886
887
                    obj.model.plotModel(tgtAxes, comp2axesMapping, wireframe);
                end
            else
                if iscell(obj.model)
                    for iRoom = 1 : numel(obj.model)
                        obj.model{iRoom}.plotModel(tgtAxes, comp2axesMapping, wireframe);
                        hold on;
                    end
                else
                    obj.model.plotModel(tgtAxes, comp2axesMapping, wireframe);
                end
            end
Philipp Schäfer's avatar
Philipp Schäfer committed
888
889
890
891
892
            
            % get and transform source and receiver data
            invertAxes = sign(comp2axesMapping);
            comp2axesMapping = abs(comp2axesMapping);
            
893
            spos = obj.getSourcePosition;
894
            spos = spos(:, comp2axesMapping).*repmat(invertAxes,size(spos,1),1);
Philipp Schäfer's avatar
Philipp Schäfer committed
895
            sview = obj.getSourceViewVectors;
896
            sview = sview(:, comp2axesMapping).*repmat(invertAxes,size(sview,1),1);
897
898
899
            snames = obj.getSourceNames;
            
            rpos = obj.getReceiverPosition;
900
            rpos = rpos(:, comp2axesMapping).*repmat(invertAxes,size(rpos,1),1);
Philipp Schäfer's avatar
Philipp Schäfer committed
901
            rview = obj.getReceiverViewVectors;
902
            rview = rview(:, comp2axesMapping).*repmat(invertAxes,size(rview,1),1);
903
904
            rnames = obj.getReceiverNames;
            
Philipp Schäfer's avatar
Philipp Schäfer committed
905
906
907
            % plot source and receivers
            plot3(spos(:,1),spos(:,2),spos(:,3),'marker','o','markersize',9,'linestyle','none','linewidth',1.5)
            plot3(rpos(:,1),rpos(:,2),rpos(:,3),'marker','x','markersize',9,'linestyle','none','linewidth',1.5)
908
            
909
            % plot view vectors (red) of sources
Philipp Schäfer's avatar
Philipp Schäfer committed
910
            quiver3(spos(:,1),spos(:,2),spos(:,3),sview(:,1),sview(:,2),sview(:,3),0,'color','r','maxheadsize',1.5,'linewidth',1.5);
911
            
912
            % plot view/up vectors (red) of receivers
Philipp Schäfer's avatar
Philipp Schäfer committed
913
            quiver3(rpos(:,1),rpos(:,2),rpos(:,3),rview(:,1),rview(:,2),rview(:,3),0,'color','r','maxheadsize',1.5,'linewidth',1.5);
914
915
            
            
916
917
            % plot up vectors (green) of sources and receivers (currently
            % deactivated)
918
919
920
921
922
            %             sup = obj.getSourceUpVectors;
            %             quiver3(spos(:,3),spos(:,1),spos(:,2),0.5*sup(:,3),0.5*sup(:,1),0.5*sup(:,2),'color','g','maxheadsize',1.5,'linewidth',1.5);
            %
            %             rup = obj.getReceiverUpVectors;
            %             quiver3(rpos(:,3),rpos(:,1),rpos(:,2),0.5*rup(:,3),0.5*rup(:,1),0.5*rup(:,2),'color','g','maxheadsize',1.5,'linewidth',1.5);
923
            
924
925
            
            % plot names
Philipp Schäfer's avatar
Philipp Schäfer committed
926
927
            text(spos(:,1)+0.2,spos(:,2),spos(:,3),snames)
            text(rpos(:,1)+0.2,rpos(:,2),rpos(:,3),rnames)
928
        end
929
930
        
        %------------------------------------------------------------------
931
        function tgtAxes = plotModelRoom(obj, tgtAxes, comp2axesMapping, wireframe)
932
933
934
935
936
937
938
939
940
941
942
943
944
            % identical to plotModel, without sound sources and receivers
            if isempty(obj.modelFileList)
                return;
            end
            
            if nargin < 4
                wireframe = 0;
            else
                if ischar(wireframe)
                    wireframe = isequal(wireframe, 'wireframe');
                end
            end
            if nargin < 3
945
                comp2axesMapping = [1 -3 2];
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
            end
            if nargin < 2
                if (ishandle(obj.plotModelHandle))
                    tgtAxes = obj.plotModelHandle;
                else
                    figure;
                    tgtAxes = gca;
                end
                
            end
            
            obj.plotModelHandle = tgtAxes;
            
            if isempty(obj.model)
                if iscell(obj.modelFileList)
                    for iRoom = 1 : numel(obj.modelFileList)
962
                        obj.model{iRoom} = itaAc3dModel(obj.modelFileList{iRoom});
963
964
965
966
                        obj.model{iRoom}.plotModel(tgtAxes, comp2axesMapping, wireframe);
                        hold on;
                    end
                else
967
                    obj.model = itaAc3dModel(obj.modelFileList);
968
969
970
971
972
973
974
975
976
977
978
979
                    obj.model.plotModel(tgtAxes, comp2axesMapping, wireframe);
                end
            else
                if iscell(obj.model)
                    for iRoom = 1 : numel(obj.model)
                        obj.model{iRoom}.plotModel(tgtAxes, comp2axesMapping, wireframe);
                        hold on;
                    end
                else
                    obj.model.plotModel(tgtAxes, comp2axesMapping, wireframe);
                end
            end
980
            
981
        end
982
        
983
        %------------------------------------------------------------------
984
        function plotMaterialsAbsorption(obj, exportPlot, fileType)
985
986
            
            if nargin < 2
987
                exportPlot = false;
988
989
            end
            
990
991
992
993
            if nargin < 3
                fileType='png';
            end
            
994
995
996
997
            freqVector = [20 25 31.5 40 50 63 80 100 125 160 200 250 315 400 500 630 800 1000 1250 1600 2000 2500 3150 4000 5000 6300 8000 10000 12500 16000 20000];
            freqLabel3rdVisual = { '', '', '31.5 Hz', '', '', '' '', '  ', '  125 Hz', ' ', ' ', ...
                '', ' ', ' ', '  500 Hz', ' ', '  ', '', '', ' ', '   2 kHz', ...
                ' ', '', '', '', '', '   8 kHz', '  ', '', '', '20 kHz'};
998
            
999
            yticks = { '0.0','', '0.20','','0.40','','0.60','','0.80','','1.0'};
1000
            
1001
1002
            allMaterials = obj.getRoomMaterialNames;
            numberMaterials = length(allMaterials);
1003
            
1004
1005
1006
            currentMaterial = itaResult;
            currentMaterial.freqVector = freqVector;
            currentMaterial.freqData = [];
1007
            
1008
1009
            for iMat=1:numberMaterials
                [absorp scatter ] = obj.getMaterial(allMaterials{iMat});
1010
                currentMaterial.freqData = [ currentMaterial.freqData absorp' ];
1011
1012
1013
                currentSurfaceArea = obj.getSurfaceAreaOfMaterial(allMaterials{iMat});
                allMaterials{iMat} = strrep(allMaterials{iMat},'_',' ');
                allMaterials{iMat} = [ allMaterials{iMat} ' (S = ' num2str(currentSurfaceArea,'%5.2f') ' m ;'];
1014
                allMaterials{iMat} = [ allMaterials{iMat} ' A (Eyring, f=1000 Hz) = ' num2str(-currentSurfaceArea*log(1-currentMaterial.freqData(18,iMat)),'%5.2f') ' m )'];
1015
            end
1016
            
1017
1018
            currentMaterial.channelNames = allMaterials;
            currentMaterial.allowDBPlot = false;
1019
            currentPlot = ita_plot_freq(currentMaterial,'LineWidth',2);
1020
            
1021
1022
1023
1024
1025
            myAxes = gca;
            for iMat=1:numberMaterials
                myAxes.Children(iMat+2).Marker = 's';
            end
            
1026
            % change format of plot
1027
1028
1029
            title('');
            ylabel('Absorption coefficient');
            xlabel('Frequency in Hz');
1030
1031
            set(myAxes,'XLim',[20 20000]);
            set(myAxes,'YLim',[0 1.05]);
1032
1033
            leg = findobj(gcf,'Tag','legend');
            set(leg,'Location','NorthWest');
1034
            set(leg,'FontSize',12);
1035
1036
1037
1038
            
            % remove [1] in legend entry
            for iMat=1:numberMaterials
                leg.String{iMat} = leg.String{iMat}(1:end-4);
1039
            end
1040
            
1041
            % export plot to raven output
1042
            if (exportPlot)
1043
1044
1045
                [pathstr,name,ext] = fileparts(obj.ravenProjectFile);
                dateTimeStr = datestr(now,30);
                dateTimeStr = strrep(dateTimeStr,'T','_');
1046
1047
                fileNamePNG = [ obj.pathResults '\Absorption_' name '_' dateTimeStr '.png'];
                fileNamePDF = [ obj.pathResults '\Absorption_' name '_' dateTimeStr '.pdf'];
1048
1049
                set(gcf,'units','normalized','outerposition',[0 0 1 1]);
                set(gcf,'PaperUnits','inches','PaperPosition',1.34*[0 0 8 5]);
1050
1051
                
                if strcmpi(fileType,'pdf')
1052
                    set(gcf,'PaperUnits','centimeters','PaperSize',[25.7, 16.5]);
1053
1054
1055
1056
1057
1058
1059
1060
                    print('-dpdf','-r200', fileNamePDF);
                    close(currentPlot);
                else
                    if ~strcmpi(fileType,'png')
                        warning('plotMaterialsAbsorption: Specified fileType not supported. Using PNG.');
                    end
                    print('-dpng','-r200', fileNamePNG);
                end
1061
1062
1063
1064
            end
        end
        
        %------------------------------------------------------------------
1065
        function plotMaterialsScattering(obj, exportPlot, fileType)
1066
            
1067
            if nargin < 2
1068
                exportPlot = false;
1069
1070
            end
            
1071
1072
1073
1074
            if nargin < 3
                fileType='png';
            end
            
1075
1076
1077
1078
            freqVector = [20 25 31.5 40 50 63 80 100 125 160 200 250 315 400 500 630 800 1000 1250 1600 2000 2500 3150 4000 5000 6300 8000 10000 12500 16000 20000];
            freqLabel3rdVisual = { '', '', '31.5 Hz', '', '', '' '', '  ', '  125 Hz', ' ', ' ', ...
                '', ' ', ' ', '  500 Hz', ' ', '  ', '', '', ' ', '   2 kHz', ...
                ' ', '', '', '', '', '   8 kHz', '  ', '', '', '20 kHz'};
1079
            
1080
            yticks = { '0.0','', '0.20','','0.40','','0.60','','0.80','','1.0'};
1081
            
1082
1083
            allMaterials = obj.getRoomMaterialNames;
            numberMaterials = length(allMaterials);
1084
            
1085
1086
1087
            currentMaterial = itaResult;
            currentMaterial.freqVector = freqVector;
            currentMaterial.freqData = [];
1088
            
1089
1090
1091
            for i=1:numberMaterials
                [absorp scatter ] = obj.getMaterial(allMaterials{i});
                currentMaterial.freqData = [ currentMaterial.freqData scatter' ];
1092
                currentSurfaceArea = obj.getSurfaceAreaOfMaterial(allMaterials{i});
1093
1094
                allMaterials{i} = strrep(allMaterials{i},'_',' ');
                allMaterials{i} = [ allMaterials{i} ' (S = ' num2str(currentSurfaceArea,'%5.2f') ' m )'];
1095
            end
1096
            
1097
1098
            currentMaterial.channelNames = allMaterials;
            currentMaterial.allowDBPlot = false;
1099
            currentPlot=ita_plot_freq(currentMaterial,'LineWidth',2);
1100
1101
1102
1103
1104
1105
            
            myAxes = gca;
            for iMat=1:numberMaterials
                myAxes.Children(iMat+2).Marker = 's';
            end
            
1106
1107
            
            % change format of plot
1108
1109
1110
            title('');
            ylabel('Scattering coefficient');
            xlabel('Frequency in Hz');
1111
1112
            set(myAxes,'XLim',[20 20000]);
            set(myAxes,'YLim',[0 1.05]);
1113
1114
            leg = findobj(gcf,'Tag','legend');
            set(leg,'Location','NorthWest');
1115
            set(leg,'FontSize',12);
1116
1117
1118
1119
1120
            
            % remove [1] in legend entry
            for iMat=1:numberMaterials
                leg.String{iMat} = leg.String{iMat}(1:end-4);
            end
1121
            
1122
            % export plot to raven output
1123
            if (exportPlot)
1124
1125
1126
                [pathstr,name,ext] = fileparts(obj.ravenProjectFile);
                dateTimeStr = datestr(now,30);
                dateTimeStr = strrep(dateTimeStr,'T','_');
1127
1128
                fileNamePNG = [ obj.pathResults '\Scattering_' name '_' dateTimeStr '.png'];
                fileNamePDF = [ obj.pathResults '\Scattering_' name '_' dateTimeStr '.pdf'];
1129
1130
                set(gcf,'units','normalized','outerposition',[0 0 1 1]);
                set(gcf,'PaperUnits','inches','PaperPosition',1.34*[0 0 8 5]);
1131
1132
                
                if strcmpi(fileType,'pdf')
1133
                    set(gcf,'PaperUnits','centimeters','PaperSize',[25.7, 16.5]);
1134
1135
1136
1137
1138
1139
1140
1141
1142
                    print('-dpdf','-r200', fileNamePDF);
                    close(currentPlot);
                else
                    if ~strcmpi(fileType,'png')
                        warning('plotMaterialsScattering: Specified fileType not supported. Using PNG.');
                    end
                    print('-dpng','-r200', fileNamePNG);
                end
                
1143
1144
1145
1146
1147
            end
        end
        
        
        
1148
1149
1150
1151
1152
1153
1154
1155
        % [Global] %
        %------------------------------------------------------------------
        function setProjectName(obj, projectName)
            obj.projectName = projectName;
            obj.rpf_ini.SetValues('Global', 'ProjectName', projectName);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
Philipp Schäfer's avatar
Philipp Schäfer committed
1156
1157
1158
1159
1160
1161
        function setPathMaterials(obj, pathMaterials)
            obj.pathMaterials = pathMaterials;
            obj.rpf_ini.SetValues('Global', 'ProjectPath_MaterialDB', pathMaterials);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
        %------------------------------------------------------------------
        function setSimulationTypeIS(obj, typeIS)
            obj.simulationTypeIS = typeIS;
            obj.rpf_ini.SetValues('Global', 'simulationTypeIS', typeIS);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setSimulationTypeRT(obj, typeRT)
            obj.simulationTypeRT = typeRT;
            obj.rpf_ini.SetValues('Global', 'simulationTypeRT', typeRT);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setGenerateRIR(obj, genRIR)
            obj.generateRIR = genRIR;
            obj.rpf_ini.SetValues('Global', 'generateRIR', genRIR);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setGenerateBRIR(obj, genBRIR)
            obj.generateBRIR = genBRIR;
            obj.rpf_ini.SetValues('Global', 'generateBRIR', genBRIR);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setGenerateISHOA(obj, genISHOA)
            obj.generateISHOA = genISHOA;
            obj.rpf_ini.SetValues('Global', 'generateISHOA', genISHOA);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setGenerateRTHOA(obj, genRTHOA)
            obj.generateRTHOA = genRTHOA;
            obj.rpf_ini.SetValues('Global', 'generateRTHOA', genRTHOA);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setGenerateISVBAP(obj, genISVBAP)
            obj.generateISVBAP = genISVBAP;
            obj.rpf_ini.SetValues('Global', 'generateISVBAP', genISVBAP);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setGenerateRTVBAP(obj, genRTVBAP)
            obj.generateRTVBAP = genRTVBAP;
            obj.rpf_ini.SetValues('Global', 'generateRTVBAP', genRTVBAP);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setExportFilter(obj, exportFilter)
            obj.exportFilter = exportFilter;
            obj.rpf_ini.SetValues('Global', 'exportFilter', exportFilter);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setExportHistogram(obj, exportHisto)
            obj.exportHistogram = exportHisto;
            obj.rpf_ini.SetValues('Global', 'exportHistogram', exportHisto);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setExportWallHitLog(obj, exportWallHitLog)
            obj.exportWallHitLog = exportWallHitLog;
            obj.rpf_ini.SetValues('Global', 'exportWallHitList', exportWallHitLog);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setExportPlaneWaveList(obj, exportPlaneWaveList)
            obj.exportPlaneWaveList = exportPlaneWaveList;
            obj.rpf_ini.SetValues('Global', 'exportPlaneWaveList', exportPlaneWaveList);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setAccelerationType(obj, accelerationType)
            obj.accelerationType = accelerationType;
            obj.rpf_ini.SetValues('Global', 'accelerationType', accelerationType);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setLogPerformance(obj, logPerformance)
            obj.logPerformance = logPerformance;
            obj.rpf_ini.SetValues('Global', 'logPerformance', logPerformance);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setPortals(obj, portalTypes, portalStatus)
            if nargin < 3
                % if only 1 parameter is given (portalTypes), interprete
                % them as portal states! (more likely to be used like this)
                obj.rpf_ini.SetValues('Portals', 'portalStatus', obj.make_proper_string(portalTypes));     % 1 = open, 0 = closed
            else
                obj.rpf_ini.SetValues('Portals', 'portalType', portalTypes);
                obj.rpf_ini.SetValues('Portals', 'portalStatus', obj.make_proper_string(portalStatus));     % 1 = open, 0 = closed
            end
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setTemperature(obj, temp)
            obj.rpf_ini.SetValues('Rooms', 'Temperature', num2str(temp));
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function temp = getTemperature(obj)
            temp = obj.rpf_ini.GetValues('Rooms', 'Temperature', -1);
        end
        
        %------------------------------------------------------------------
        function setHumidity(obj, humid)
            obj.rpf_ini.SetValues('Rooms', 'Humidity', num2str(humid));
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function humid = getHumidity(obj)
            humid = obj.rpf_ini.GetValues('Rooms', 'Humidity', -1);
        end
        
        %------------------------------------------------------------------
        function setPressure(obj, press)
            obj.rpf_ini.SetValues('Rooms', 'Pressure', num2str(press));
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function press = getPressure(obj)
            press = obj.rpf_ini.GetValues('Rooms', 'Pressure', -1);
        end
        
        %------------------------------------------------------------------
        function enableAirAbsorption(obj)
            obj.rpf_ini.SetValues('Rooms', 'noAirAbsorption', 0);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function disableAirAbsorption(obj)
            obj.rpf_ini.SetValues('Rooms', 'noAirAbsorption', 1);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
1318
1319
1320
        %------------------------------------------------------------------
        function airAbsEnabled = getAirAbsorptionEnabled(obj)
            airAbsEnabled = ~obj.rpf_ini.GetValues('Rooms', 'noAirAbsorption', 0);
1321
        end
1322
        
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
        % [PrimarySources] %
        %------------------------------------------------------------------
        function setSourceNames(obj, sourceNames)
            if iscell(sourceNames)
                obj.sourceNameString = obj.cat_cell_of_strings(sourceNames);
                obj.sourceNames      = sourceNames;
            else
                obj.sourceNameString = sourceNames;
                obj.sourceNames      = textscan(obj.sourceNameString, '%s', 'Delimiter', ',');
                obj.sourceNames      = obj.sourceNames{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            end
            obj.rpf_ini.SetValues('PrimarySources', 'sourceNames', obj.sourceNameString);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function directivityName = getSourceDirectivity(obj, srcID)
            
            readstring = obj.rpf_ini.GetValues('PrimarySources', 'sourceDirectivity', '');
            if ~isempty(readstring)
                
                readstring   = textscan(readstring, '%s', 'Delimiter', ',');
                readstring   = readstring{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
                if nargin<2
                    directivityName=readstring;
                else
                    directivityName=readstring(srcID);
                end
                
            else
                obj.sourceDirectivity   = {};
            end
            
            % %            Original
            %             if iscell(obj.sourceDirectivity)
            %                 directivityName = obj.sourceDirectivity{sourceID + 1};
            %             else
            %                 obj.sourceDirectivity   = textscan(obj.sourceDirectivityString, '%s', 'Delimiter', ',');
            %                 obj.sourceDirectivity   = obj.sourceDirectivity{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            %                 directivityName = obj.sourceDirectivity{sourceID + 1};
            %             end
        end
        
        %------------------------------------------------------------------
        function setSourceDirectivity(obj, directivity)
            if iscell(directivity)
                obj.sourceDirectivityString = obj.cat_cell_of_strings(directivity);
                obj.sourceDirectivity   = directivity;
            else
                obj.sourceDirectivityString = directivity;
                obj.sourceDirectivity   = textscan(obj.sourceDirectivityString, '%s', 'Delimiter', ',');
                obj.sourceDirectivity   = obj.sourceDirectivity{1}; % textscan liefert cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            end
            obj.rpf_ini.SetValues('PrimarySources', 'sourceDirectivity', obj.sourceDirectivityString);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
        
        %------------------------------------------------------------------
        function setSourceDirectivityPath(obj, myPath)
            %
            %   setSourceDirectivityPath(path)
            %
            %      Set the RAVEN source directivity database path. Here all
            %      directivities (.daff files) should be located
            %
            %      To generate new files, check out opendaff in the 
            %      \applications\VirtualAcoustics\openDAFF\
            %
            %      RAVEN currently only supports OpenDAFFv1.5 files
            %
1394
            obj.pathDirectivities = myPath;
1395
            obj.rpf_ini.SetValues('Global', 'ProjectPath_DirectivityDB', myPath);
1396
1397
1398
1399
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        
1400
1401
        %------------------------------------------------------------------
        function pos = getSourcePosition(obj, srcID)
1402
            
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
            all_pos = obj.rpf_ini.GetValues('PrimarySources', 'sourcePositions');
            if (nargin < 2)
                pos = reshape(all_pos',3,length(all_pos)/3)';
            else
                pos = all_pos((srcID*3 + 1) : (srcID*3 + 3));
            end
        end
        %------------------------------------------------------------------
        function setSourcePositions(obj, pos, coord_trafo)
            %setSourcePositions(pos, [coord_trafo])
            %   coord_trafo: 3-element vector
            %                1. element: which of the given axis to use as x-coordinates
            %                2. element: which of the given axis to use as y-coordinates
            %                3. element: which of the given axis to use as z-coordinates
            
            % if input is string convert to matrix
            if ischar(pos)
                pos = reshape(sscanf(pos, '%f,'), 3, numel(pos)/3)';
            end
            
            % if input is itaCoordinates convert to matrix
            if isa(pos, 'itaCoordinates')
                pos = pos.cart;
            end
            
            % check dimensions
            if size(pos, 2) ~= 3
                error('Positions must be given in vector (1x3) or matrix (Nx3) format.');
            end
            
            % store matrix in RavenProject object
            obj.sourcePositions = pos;
            
            % store positions in .rpf file on disk
            if nargin > 2
                obj.rpf_ini.SetValues('PrimarySources', 'sourcePositions', obj.make_proper_string( ...
                    [sign(coord_trafo(1)) .* pos(:, abs(coord_trafo(1))), ...
                    sign(coord_trafo(2)) .* pos(:, abs(coord_trafo(2))), ...
                    sign(coord_trafo(3)) .* pos(:, abs(coord_trafo(3)))] ));
            else
                obj.rpf_ini.SetValues('PrimarySources', 'sourcePositions', obj.make_proper_string(pos));
            end
            
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setSourceViewVectors(obj, view)
            obj.sourceViewVectors = view;
            if isnumeric(view) || iscell(view)
                obj.rpf_ini.SetValues('PrimarySources', 'sourceViewVectors', obj.make_proper_string(view));
            else
                obj.rpf_ini.SetValues('PrimarySources', 'sourceViewVectors', view);
            end
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setSourceUpVectors(obj, up)
            obj.sourceUpVectors = up;
            if isnumeric(up) || iscell(up)
                obj.rpf_ini.SetValues('PrimarySources', 'sourceUpVectors', obj.make_proper_string(up));
            else
                obj.rpf_ini.SetValues('PrimarySources', 'sourceUpVectors', up);
            end
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setSourceSoundStates(obj, state)
            obj.sourceSoundStates   = state;
            if isnumeric(state) || iscell(state)
                obj.rpf_ini.SetValues('PrimarySources', 'sourceSoundStates', obj.make_proper_string(state));
            else
                obj.rpf_ini.SetValues('PrimarySources', 'sourceSoundStates', state);
            end
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function setSourceLevels(obj, levels)
            obj.sourceSoundLevels   = levels;
            if isnumeric(levels) || iscell(levels)
                obj.rpf_ini.SetValues('PrimarySources', 'sourceSoundLevels', obj.make_proper_string(levels));
            else
                obj.rpf_ini.SetValues('PrimarySources', 'sourceSoundLevels', levels);
            end
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        % [Receiver] %
        %------------------------------------------------------------------
        function setReceiverNames(obj, rec_names)
            if iscell(rec_names)
                obj.receiverNameString = obj.cat_cell_of_strings(rec_names);
                obj.receiverNames      = rec_names;
            else
                obj.receiverNameString = rec_names;
                obj.receiverNames      = textscan(obj.receiverNameString, '%s', 'Delimiter', ',');
                obj.receiverNames      = obj.receiverNames{1}; % textscan liefer cell array in nochmal einer zelle, diese doppelkapselung wird hier rckgngig gemacht
            end
            obj.rpf_ini.SetValues('Receiver', 'receiverNames', obj.receiverNameString);
            obj.rpf_ini.WriteFile(obj.ravenProjectFile);
        end
        
        %------------------------------------------------------------------
        function pos = getReceiverPosition(obj, recID)
            all_pos = obj.rpf_ini.GetValues('Receiver', 'receiverPositions');
            if (nargin < 2)
                pos = reshape(all_pos',3,length(all_pos)/3)';
            else
                pos = all_pos((recID*3 + 1) : (recID*3 + 3));
            end
        end
        
        %------------------------------------------------------------------
        function rvv = getReceiverViewVectors(obj, recID)
1520
            
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530