diff simScene.m @ 14:b1901e8d8f5f

initial commit
author Mathieu Lagrange <mathieu.lagrange@cnrs.fr>
date Tue, 17 Mar 2015 09:34:13 +0100
parents
children 69410ac2a50d
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simScene.m	Tue Mar 17 09:34:13 2015 +0100
@@ -0,0 +1,208 @@
+function [] = simScene(inputPath,outputPath,score,varargin)
+% [] = simScene(inputPath,outputPath,score,[opts ... ])
+%
+% Generate a simulated auditory scene by mixing randomly chosen samples.
+% The samples and their mixing properties are chosen partially randomly
+% following user-provided guidelines.
+%
+% Required input variables are:
+%
+% - inputPath: a dataset of isolated sound events and backgrounds
+%             respectively located in inputPat/event/ and
+%             inputPat/background
+%
+% - outputPath: the repository where simscene will write the simulated scene
+%              as well as the annotations
+%
+% - score: a structure describing the scene to simulate
+%
+%   score.sceneDuration: length of the simulated scene in second
+%
+%   score.backgrounds: Backgrounds are continuous sounds that keep going
+%         over the whole duration of the scene. Several background samples
+%         may be mixed together. If 'sceneDuration' is  more than the
+%         natural length  of one of the selected bg sounds, they will be
+%         looped as necessary -- that may not sound great, depending on the
+%         sound... The format of the 'background' field controlling their
+%         selection   and use is:
+%
+%         {{'<bg 1 label>','<bg 1 sampleId>', 1},
+%          {'<bg 2 label>','<bg 2 sampleId>', <bg 2 snr>}...}
+%
+%         The value of 'snr' is ignored for the first bg sound. For the
+%         following ones, it will be evaluated against the sum of the
+%         previous ones. The value of 'Label' is the label of the
+%         background track. Simscene will use the value 'sampleId' to load
+%         the background sample(s) located in inputpath/background.
+%         Simscene will only use background sample(s) having a name
+%         containing the value 'sampleId'.
+%
+%  score.events: The 'events' is an array of cell arrays containg data use
+%        to  simulated the scenes. Event contains the following data:
+%
+%        {{'<event 1 label>',
+%          '<event 1 sampleId>',
+%           <event 1 ebr>,
+%           <event 1 ebr_stddev>,
+%           <event 1 mean_time_between_instances>,
+%           <event 1 time_between_instances_stddev>,
+%           <event 1 start_time>, 
+%           <event 1 end_time>,
+%           <event 1 fade_in_time>, 
+%           <event 1 fade_out_time>},
+%         {'<event 2 ...> ...},
+%         {'<event 3 ...> ...}
+%        ...}
+%
+%        If <mean_time_between_instances> is 0, then it will be set to the
+%        sample  length (so if <time_between_instances_stddev> is also 0,
+%        the sample will be looped).
+%        If <mean_time_between_instances> is -1, then the sound will be
+%        played just once. The considered EBR value is the maximum EBR
+%        of the fg sample relative to the bg on windows of 1000 samples.
+%        The considered bg for this is the  mix of all specified bgs.
+%
+%  This version of simscene allows a lot of options to be controlled, as
+%  optional  'name', value pairs from the 4th argument. Here is a brief 
+%  description of the optional parameters:
+% 
+%  - timeMode: control a time spacing between events. 
+%  		'generate' (default): values must be set for each track using the 
+%                             score control structure
+%  		'abstract': values are computed from an abstract representation of 
+%                   an existing acoustic scene given as parameter
+%  		'replicate': values are replicated from an existing acoustic scene 
+%                    given as parameter
+%  		
+%  - ebrMode: control the Event to Background power level Ratio (EBR) of events. 
+%  		Possible options are: 'generate' (default), 'abstract', 'replicate', see above.
+%
+% If ebrMode is set to 'replicate' or 'abstract', and score.events exist, 
+% simScene will use the values <ebr> and <ebr_stddev> as offsets for 
+% the class <label>. 
+% If timeMode is set to 'abstract' and score.events exist, simScene will use 
+% the values <mean_time_between_instances> and <time_between_instances_stddev>.
+% as offsets for the class <label>. 
+% If one of the mode is not set to 'generate' and score.events exist, SimScene 
+% will also use the values <start_time>, <end_time>, <fade_in_time>,  <fade_out_time> 
+% and '<sampleId>' of score.events, provided they are not equal to 0 or
+% empty.
+%  		
+%  - instanceAnnotFile: if timeMode and / or ebrMode are set to 'abstract' 
+%                       or 'replicate', this parameter is the path to the 
+%                       annotation of the reference scene. Annotation must 
+%                       be provided as a Comma Separated Value (CSV) file 
+%                       with one event per line with class identifier as a 
+%                       string, onset and offset times in second as floating 
+%                       point value.
+%
+%  - instanceAudioFile: if timeMode and / or ebrMode are set to 'abstract' 
+%                       or 'replicate', this parameter is the path to the wav 
+%                       file of the reference scene sampled at 44100 Hz.
+%  
+%  - displayFigures: Boolean (default 0), save pictures (piano roll, time 
+%                    domain stacked visualization, overlaid spectrogram)
+% 
+%  - outputFileName: name of generated files with no extension
+%  
+%  - sampleChoice: method for choosing sample to schedule within a track
+%  		'random': unconstrained sampling
+%  		'close': choose among the sampling dataset the sample that 
+%                has the closest duration to the reference one. 
+%                This mode is available only for the replicate timeMode.
+%  
+%  - minSpace: floating point value (default -1: overlapping between events allowed): 
+%              minimal spacing in seconds between successive events
+%  
+%  - endCut: Boolean (default 0): adjust the duration of the last sample of 
+%            each track if the latter ends after the track duration. 
+%            If 1, cut the last sample to the track duration. If
+%            0, the last sample is removed.
+%
+%  SceneSchedule and SceneObject:
+%
+%  - sceneObjects: This vector will contain detailed information concerning 
+%                  all the samples selected to build this scene.
+%                    
+%  - sceneSchedule: This vector will contain all scheduling information 
+%                   (i.e. what sample goes where, with what scaling factor). 
+%                   The sample indices stored in it refer to the position 
+%                   in the previous vector.
+%
+%  SceneSchedule, SceneObject, as well as score are saved in the .mat
+%  annotation file.
+
+% This program was written by Mathias Rossignol & Grégoire Lafay
+% is Copyright (C) 2015 IRCAM <http://www.ircam.fr>
+%
+% This program is free software: you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the Free
+% Software Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+% for more details.
+%
+% You should have received a copy of the GNU General Public License along
+% with this program.  If not, see <http://www.gnu.org/licenses/>.
+%
+% Uses Mark Paskin's process_options.m from KPMtools
+
+addpath(genpath('nonExposed'));
+
+[timeMode,ebrMode,instanceAnnotFile,instanceAudioFile,displayFigures,sampleChoice,outputFileName,minSpace,endCut]=process_options(varargin,'timeMode','generate','ebrMode','generate','instanceAnnotFile','none','instanceAudioFile','none','displayFigures','1','sampleChoice','random','outputFileName','simulatedScene','minSpace',-1,'endCut',0);
+
+check_options(timeMode,ebrMode,score)
+
+%% Get score (only if at least one of the modes is not set to generate).
+%  Else use score inpu variable
+if (~strcmp(timeMode,'generate') || ~strcmp(ebrMode,'generate'))
+    template=getTemplate(instanceAnnotFile,instanceAudioFile);
+    if isfield(score,'events')
+        score.events=addUserOffsets(template.class,score.events,timeMode,ebrMode);
+    else
+        warning('score.event is empty: score.event will be created from the scene to replicate');
+        score.events=template.class;
+    end
+    if ~isfield(score,'sceneDuration')
+        score.sceneDuration=template.sceneDuration;
+    end
+end
+
+%% Get sceneSchedule and sceneObjects
+[sceneSchedule,sceneObjects]=getBackground(inputPath,score);
+[sceneSchedule,sceneObjects]=getEvent(sceneSchedule,sceneObjects,inputPath,score,timeMode,ebrMode,strcmp(sampleChoice,'random'));
+
+%% Manage overlapping
+if minSpace>=0
+    [sceneSchedule] = manageOverlapping(sceneSchedule,minSpace);
+end
+
+
+%% Generate Scene
+if (~exist(outputPath, 'dir'))
+    mkdir(outputPath)
+end
+if (~exist([outputPath,'annotation'], 'dir'))
+    mkdir([outputPath,'sound'])
+end
+if (~exist([outputPath,'annotation'], 'dir'))
+    mkdir([outputPath,'annotation'])
+end
+
+[simsSceneWav,sceneSchedule] = generateScene(sceneSchedule,sceneObjects,score,inputPath,outputPath,outputFileName,displayFigures,timeMode,endCut);
+
+%% Check simulated scene
+
+checkClassPresence(sceneSchedule,sceneObjects);
+
+if minSpace>=0
+    checkOverlapping(sceneSchedule,score.sceneDuration)
+end
+
+%% Generate Sound
+wavwrite(simsSceneWav,44100,[outputPath,'sound/',outputFileName,'.wav']);
+
+end