annotate nonExposed/generateScene.m @ 51:ebf92ed7d680 tip master

Added -fd (--full-duration) argument.
author Emmanouil Theofanis Chourdakis <e.t.chourdakis@qmul.ac.uk>
date Sun, 30 Sep 2018 13:21:49 +0100
parents 39399de892ef
children
rev   line source
gregoirelafay@17 1 function [sceneSchedule] = generateScene (sceneSchedule,sceneObjects,score,inputPath,outputPath,outputFileName,figuresOption,timeMode,endCut,norm,sr,channelOption)
mathieu@14 2 % function [w,sceneSchedule] = generateScene (sceneSchedule,sceneObjects,score,inputPath,outputPath,outputFileName,displayFigures,timeMode,endCut)
mathieu@14 3 % This function does the actual job of loading, scaling, positioning and
mathieu@14 4 % mixing the various samples to generate a scene, based on the
gregoire@16 5 % specifications given by its parameters.
mathieu@14 6
mathieu@14 7 % This program was written by Mathias Rossignol & Grégoire Lafay
mathieu@14 8 % is Copyright (C) 2015 IRCAM <http://www.ircam.fr>
mathieu@14 9 %
mathieu@14 10 % This program is free software: you can redistribute it and/or modify it
mathieu@14 11 % under the terms of the GNU General Public License as published by the Free
mathieu@14 12 % Software Foundation, either version 3 of the License, or (at your option)
mathieu@14 13 % any later version.
mathieu@14 14 %
mathieu@14 15 % This program is distributed in the hope that it will be useful, but
mathieu@14 16 % WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
mathieu@14 17 % or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mathieu@14 18 % for more details.
mathieu@14 19 %
mathieu@14 20 % You should have received a copy of the GNU General Public License along
mathieu@14 21 % with this program. If not, see <http://www.gnu.org/licenses/>.
mathieu@14 22
mathieu@14 23
mathieu@14 24 % All instances of one sample will appear on a given track, before
mathieu@14 25 % everything is mixed together, making it possible to apply track-specific
mathieu@14 26 % effects or generate nice colorful representations
gregoire@16 27
mathieu@14 28
mathieu@14 29 % We also generate a "bg" track with all background samples, against which
mathieu@14 30 % the snr of fg sounds will be evaluated
gregoire@16 31
gregoire@16 32 %% Init tab
gregoire@16 33
gregoire@16 34 trackLength = sr*score.sceneDuration;
gregoire@16 35
gregoire@16 36 tracks = zeros(length(sceneObjects), trackLength);
mathieu@14 37 bg = zeros(trackLength, 1);
mathieu@14 38
mathieu@14 39 dominantTrack = zeros(1,trackLength) + 1;
mathieu@14 40 dominantObject = zeros(1,trackLength) + 1;
mathieu@14 41 dominantEnergy = zeros(1,trackLength);
mathieu@14 42 simulatedEBR = zeros(length(sceneSchedule),2);
mathieu@14 43 objNum = 1;
mathieu@14 44
mathieu@14 45 %% Create sceneSchedule
mathieu@14 46 id2remove=[];
mathieu@14 47 for i=1:length(sceneSchedule)
mathieu@14 48 id = sceneSchedule(i).classId;
mathieu@14 49 if (sceneSchedule(i).isBackground)
gregoire@24 50 if strcmp(sceneObjects(i).classLabel,'noise')
gregoire@24 51 waves=score.backgrounds{1}{2}';
gregoire@24 52 else
gregoire@24 53 waves = audioread([inputPath 'background/' sceneObjects(id).names{1}]);
gregoire@24 54 [MinSizeWaves,indMinSizeWaves]=min(size(waves));
gregoire@24 55 if MinSizeWaves==2
gregoire@24 56 waves=mean(waves,indMinSizeWaves);
gregoire@24 57 end
gregoire@23 58 end
mathieu@14 59 scale = 1;
mathieu@14 60 if (i>1)
gregoire@16 61 scale = adjustScaleForEBR(waves, bg, 1, sceneSchedule(i).ebr, 1, 0.01);
mathieu@14 62 end
gregoire@16 63 if (length(waves) < trackLength)
mathieu@14 64 % need to loop the sample to fill the bg. Linear crossfade
gregoire@19 65 fadeLen = sr;
mathieu@14 66 fadeIn = transpose(0:1/fadeLen:1);
mathieu@14 67 fadeOut = transpose(1:-1/fadeLen:0);
gregoire@19 68 loop = waves;
mathieu@14 69 loop(1:fadeLen) = loop(1:fadeLen) .* fadeIn(1:fadeLen);
mathieu@14 70 loop(length(loop)-fadeLen+1:length(loop)) = loop(length(loop)+1-fadeLen:length(loop)) .* fadeOut(1:fadeLen);
gregoire@19 71 loop = scale * loop';
gregoire@19 72 startLoop=waves;
gregoire@19 73 startLoop(length(startLoop)-fadeLen+1:length(startLoop)) = startLoop(length(startLoop)+1-fadeLen:length(startLoop)) .* fadeOut(1:fadeLen);
gregoire@19 74 startLoop = scale * startLoop';
mathieu@14 75 for l=0:floor(trackLength/(length(loop)-fadeLen))
mathieu@14 76 t1 = 1+l*(length(loop)-fadeLen);
mathieu@14 77 t2 = min(length(bg), t1+length(loop)-1);
gregoire@19 78 if l
gregoire@19 79 tracks(id,t1:t2) = tracks(id,t1:t2) + loop(1:t2-t1+1);
gregoire@19 80 else
gregoire@19 81 tracks(id,t1:t2) = tracks(id,t1:t2) + startLoop(1:t2-t1+1);
gregoire@19 82 end
mathieu@14 83 end
mathieu@14 84 else
gregoire@16 85 dim = min(trackLength, length(waves));
gregoire@19 86 tracks(id,1:dim) = tracks(id,1:dim) + scale*waves(1:dim)';
mathieu@14 87 end
mathieu@14 88 if (i==1)
mathieu@14 89 bg = tracks(id,:);
mathieu@14 90 else
mathieu@14 91 bg = bg+tracks(id,:);
mathieu@14 92 end
mathieu@14 93 else
mathieu@14 94 objNum = objNum+1;
mathieu@14 95 inst = sceneSchedule(i).instance;
gregoire@16 96 waves = audioread([inputPath 'event/' sceneObjects(id).names{inst}]);
gregoire@23 97 [MinSizeWaves,indMinSizeWaves]=min(size(waves));
gregoire@23 98 if MinSizeWaves==2
gregoire@23 99 waves=mean(waves,indMinSizeWaves);
gregoire@23 100 end
mathieu@14 101 pos = max(1,floor(sr*sceneSchedule(i).position));
mathieu@14 102
mathieu@14 103 switch timeMode
mathieu@14 104 case {'replicate'}
gregoire@16 105 if(length(waves)/sr - sceneSchedule(i).duration > 0.5)
mathieu@14 106 endTime = round(sceneSchedule(i).duration*sr);
mathieu@14 107 else
gregoire@16 108 endTime = length(waves);
mathieu@14 109 end
mathieu@14 110 case {'abstract'}
mathieu@14 111 endTime = round(sceneSchedule(i).duration*sr);
mathieu@14 112 otherwise
gregoire@16 113 endTime = length(waves);
mathieu@14 114 end
gregoire@16 115
mathieu@14 116 if endCut
gregoire@16 117 pos2Test=pos;
mathieu@14 118 else
mathieu@14 119
gregoire@16 120 pos2Test=pos+endTime-1;
mathieu@14 121 end
mathieu@14 122
mathieu@14 123 if(pos2Test<round(sceneObjects(sceneSchedule(i).classId).trackLength*sr))
mathieu@14 124 t2 = min(pos+endTime-1, round(sceneObjects(sceneSchedule(i).classId).trackLength*sr));
gregoire@16 125 wav2use=waves(1:t2-pos+1);
mathieu@14 126 sceneSchedule(i).duration=length(wav2use)/sr;
mathieu@14 127 scale = adjustScaleForEBR(wav2use, bg, pos, sceneSchedule(i).ebr, 1, 0.01);
mathieu@14 128
mathieu@14 129 [~,bgEnergy] = powspec(bg(pos:t2));
mathieu@14 130 [~,evEnergy] = powspec(scale*wav2use.');
mathieu@14 131 labelStart = min(find(bgEnergy<evEnergy));
mathieu@14 132 labelEnd = max(find(bgEnergy<evEnergy));
mathieu@14 133 for t=labelStart:labelEnd
mathieu@14 134 if evEnergy(t)>dominantEnergy(pos+t)
mathieu@14 135 dominantObject(pos+round(t*(t2-pos)/length(bgEnergy))) = objNum;
mathieu@14 136 dominantEnergy(pos+round(t*(t2-pos)/length(bgEnergy))) = evEnergy(t);
mathieu@14 137 end
mathieu@14 138 end
mathieu@14 139 dominantObject(min(find(dominantObject==objNum)):max(find(dominantObject==objNum))) = objNum;
mathieu@14 140 dominantTrack(dominantObject==objNum) = id;
mathieu@14 141
mathieu@14 142 tracks(id, pos:t2) = tracks(id, pos:t2) + scale*wav2use.';
mathieu@14 143 %% Store EBR and event locations
mathieu@14 144 simulatedEBR(i,1) = ebr(tracks(id, pos:t2),tracks(1, pos:t2));
mathieu@14 145 simulatedEBR(i,2)=pos;
mathieu@14 146 else
mathieu@14 147 id2remove=[id2remove i];
mathieu@14 148 end
mathieu@14 149 end
mathieu@14 150 end
mathieu@14 151
mathieu@14 152 sceneSchedule(id2remove)=[];
mathieu@14 153 % checkClassPresence(sceneSchedule,sceneObjects);
mathieu@14 154
mathieu@31 155
mathieu@14 156 save ([outputPath 'annotation/' outputFileName '.mat'],'score', 'sceneObjects', 'sceneSchedule','dominantTrack', 'dominantObject','simulatedEBR');
mathieu@14 157 saveAnnotationTxt(sceneSchedule,outputPath,outputFileName);
mathieu@14 158
gregoire@19 159 w = sum(tracks,1);
gregoire@19 160 if norm %Normalize to [-norm,norm]
gregoire@19 161 w = w*norm/max(abs(w));
gregoire@19 162 end
gregoire@19 163
gregoirelafay@26 164 audiowrite([outputPath 'sound/' outputFileName '.wav'],w,sr);
gregoire@19 165
gregoirelafay@17 166 switch channelOption
gregoire@19 167 case 1
gregoirelafay@17 168 if norm %Normalize to [-norm,norm]
gregoire@19 169 tracks = tracks*norm/max(abs(sum(tracks,1)));
gregoirelafay@17 170 end
gregoire@19 171 audiowrite([outputPath 'sound/' outputFileName '_channel_split' '.wav'],tracks',sr);
gregoirelafay@17 172 case 2
gregoire@19 173 if norm %Normalize to [-norm,norm]
mathieu@34 174 tracks = tracks*norm/(1.05*max(abs(sum(tracks,1))));
gregoirelafay@17 175 end
gregoirelafay@17 176 for jj=1:size(tracks,1)
gregoire@19 177 audiowrite([outputPath 'sound/' outputFileName '_channel_' num2str(jj) '_class_' sceneObjects(jj).classLabel '.wav'],tracks(jj,:),sr);
gregoirelafay@17 178 end
gregoire@16 179 end
gregoire@19 180
gregoire@16 181
gregoire@16 182 if figuresOption
mathieu@34 183 settingFigure.cmap = pleasantnessColormap(sceneObjects);
mathieu@34 184 if any(~sum(settingFigure.cmap, 2))
mathieu@34 185 fprintf(2, 'Unable to get some of the pleasantness tags, revert to randomized colors');
mathieu@34 186 settingFigure.cmap = randomColormap(sceneObjects);
mathieu@34 187 end
gregoire@16 188 settingFigure.width=29.7; % cm
gregoire@16 189 settingFigure.height=21; % cm
gregoire@16 190 settingFigure.FontSize=16;
gregoire@16 191 settingFigure.sr=sr;
gregoire@16 192 settingFigure.sceneDuration=score.sceneDuration;
mathieu@14 193
mathieu@34 194 nbBg = 0;
mathieu@34 195 for k=1:length(sceneObjects)
mathieu@34 196 if sceneObjects(k).isBackground
mathieu@34 197 nbBg = nbBg+1;
mathieu@34 198 bgo(nbBg, :) = resample(abs(tracks(k, :)), 1, 44100);
mathieu@34 199 end
mathieu@34 200 end
mathieu@34 201
mathieu@34 202
mathieu@34 203
mathieu@34 204 [~, bgOrder] = sort(mean(bgo, 2)./median(bgo, 2));
mathieu@34 205 [~, eventOrder] = sort(sum(tracks(nbBg+1:end,:)==0, 2));
mathieu@34 206 trackOrder = [bgOrder; eventOrder+nbBg];
mathieu@34 207 tracks = tracks(trackOrder, :);
mathieu@34 208 sceneObjects = sceneObjects(trackOrder);
mathieu@34 209 settingFigure.cmap = settingFigure.cmap(trackOrder, :);
mathieu@34 210
gregoire@16 211 coloredSpectrumVisualization(tracks,1,settingFigure,figuresOption,[outputPath 'annotation/' outputFileName,'-spectrum.png']);
gregoire@16 212 timeDomainVisualization(tracks,2,settingFigure,figuresOption,[outputPath 'annotation/' outputFileName,'-timeDomain.png']);
gregoire@16 213 pianoRollVisualization(sceneObjects,sceneSchedule,score,3,settingFigure,figuresOption,[outputPath 'annotation/' outputFileName,'-pianoRoll.png'])
mathieu@14 214 end