annotate nonExposed/generateScene.m @ 23:0163f857f13f

fix merge stereo
author Gregoire Lafay <gregoire.lafay@irccyn.ec-nantes.fr>
date Fri, 15 Jan 2016 15:46:47 +0100
parents 8d33767e070a
children 2abd1116ae14
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@16 50 waves = audioread([inputPath 'background/' sceneObjects(id).names{1}]);
gregoire@23 51 [MinSizeWaves,indMinSizeWaves]=min(size(waves));
gregoire@23 52 if MinSizeWaves==2
gregoire@23 53 waves=mean(waves,indMinSizeWaves);
gregoire@23 54 end
mathieu@14 55 scale = 1;
mathieu@14 56 if (i>1)
gregoire@16 57 scale = adjustScaleForEBR(waves, bg, 1, sceneSchedule(i).ebr, 1, 0.01);
mathieu@14 58 end
gregoire@16 59 if (length(waves) < trackLength)
mathieu@14 60 % need to loop the sample to fill the bg. Linear crossfade
gregoire@19 61 fadeLen = sr;
mathieu@14 62 fadeIn = transpose(0:1/fadeLen:1);
mathieu@14 63 fadeOut = transpose(1:-1/fadeLen:0);
gregoire@19 64 loop = waves;
mathieu@14 65 loop(1:fadeLen) = loop(1:fadeLen) .* fadeIn(1:fadeLen);
mathieu@14 66 loop(length(loop)-fadeLen+1:length(loop)) = loop(length(loop)+1-fadeLen:length(loop)) .* fadeOut(1:fadeLen);
gregoire@19 67 loop = scale * loop';
gregoire@19 68 startLoop=waves;
gregoire@19 69 startLoop(length(startLoop)-fadeLen+1:length(startLoop)) = startLoop(length(startLoop)+1-fadeLen:length(startLoop)) .* fadeOut(1:fadeLen);
gregoire@19 70 startLoop = scale * startLoop';
mathieu@14 71 for l=0:floor(trackLength/(length(loop)-fadeLen))
mathieu@14 72 t1 = 1+l*(length(loop)-fadeLen);
mathieu@14 73 t2 = min(length(bg), t1+length(loop)-1);
gregoire@19 74 if l
gregoire@19 75 tracks(id,t1:t2) = tracks(id,t1:t2) + loop(1:t2-t1+1);
gregoire@19 76 else
gregoire@19 77 tracks(id,t1:t2) = tracks(id,t1:t2) + startLoop(1:t2-t1+1);
gregoire@19 78 end
mathieu@14 79 end
mathieu@14 80 else
gregoire@16 81 dim = min(trackLength, length(waves));
gregoire@19 82 tracks(id,1:dim) = tracks(id,1:dim) + scale*waves(1:dim)';
mathieu@14 83 end
mathieu@14 84 if (i==1)
mathieu@14 85 bg = tracks(id,:);
mathieu@14 86 else
mathieu@14 87 bg = bg+tracks(id,:);
mathieu@14 88 end
mathieu@14 89 else
mathieu@14 90 objNum = objNum+1;
mathieu@14 91 inst = sceneSchedule(i).instance;
gregoire@16 92 waves = audioread([inputPath 'event/' sceneObjects(id).names{inst}]);
gregoire@23 93 [MinSizeWaves,indMinSizeWaves]=min(size(waves));
gregoire@23 94 if MinSizeWaves==2
gregoire@23 95 waves=mean(waves,indMinSizeWaves);
gregoire@23 96 end
mathieu@14 97 pos = max(1,floor(sr*sceneSchedule(i).position));
mathieu@14 98
mathieu@14 99 switch timeMode
mathieu@14 100 case {'replicate'}
gregoire@16 101 if(length(waves)/sr - sceneSchedule(i).duration > 0.5)
mathieu@14 102 endTime = round(sceneSchedule(i).duration*sr);
mathieu@14 103 else
gregoire@16 104 endTime = length(waves);
mathieu@14 105 end
mathieu@14 106 case {'abstract'}
mathieu@14 107 endTime = round(sceneSchedule(i).duration*sr);
mathieu@14 108 otherwise
gregoire@16 109 endTime = length(waves);
mathieu@14 110 end
gregoire@16 111
mathieu@14 112 if endCut
gregoire@16 113 pos2Test=pos;
mathieu@14 114 else
mathieu@14 115
gregoire@16 116 pos2Test=pos+endTime-1;
mathieu@14 117 end
mathieu@14 118
mathieu@14 119 if(pos2Test<round(sceneObjects(sceneSchedule(i).classId).trackLength*sr))
mathieu@14 120 t2 = min(pos+endTime-1, round(sceneObjects(sceneSchedule(i).classId).trackLength*sr));
gregoire@16 121 wav2use=waves(1:t2-pos+1);
mathieu@14 122 sceneSchedule(i).duration=length(wav2use)/sr;
mathieu@14 123 scale = adjustScaleForEBR(wav2use, bg, pos, sceneSchedule(i).ebr, 1, 0.01);
mathieu@14 124
mathieu@14 125 [~,bgEnergy] = powspec(bg(pos:t2));
mathieu@14 126 [~,evEnergy] = powspec(scale*wav2use.');
mathieu@14 127 labelStart = min(find(bgEnergy<evEnergy));
mathieu@14 128 labelEnd = max(find(bgEnergy<evEnergy));
mathieu@14 129 for t=labelStart:labelEnd
mathieu@14 130 if evEnergy(t)>dominantEnergy(pos+t)
mathieu@14 131 dominantObject(pos+round(t*(t2-pos)/length(bgEnergy))) = objNum;
mathieu@14 132 dominantEnergy(pos+round(t*(t2-pos)/length(bgEnergy))) = evEnergy(t);
mathieu@14 133 end
mathieu@14 134 end
mathieu@14 135 dominantObject(min(find(dominantObject==objNum)):max(find(dominantObject==objNum))) = objNum;
mathieu@14 136 dominantTrack(dominantObject==objNum) = id;
mathieu@14 137
mathieu@14 138 tracks(id, pos:t2) = tracks(id, pos:t2) + scale*wav2use.';
mathieu@14 139 %% Store EBR and event locations
mathieu@14 140 simulatedEBR(i,1) = ebr(tracks(id, pos:t2),tracks(1, pos:t2));
mathieu@14 141 simulatedEBR(i,2)=pos;
mathieu@14 142 else
mathieu@14 143 id2remove=[id2remove i];
mathieu@14 144 end
mathieu@14 145 end
mathieu@14 146 end
mathieu@14 147
mathieu@14 148 sceneSchedule(id2remove)=[];
mathieu@14 149 % checkClassPresence(sceneSchedule,sceneObjects);
mathieu@14 150
mathieu@14 151 save ([outputPath 'annotation/' outputFileName '.mat'],'score', 'sceneObjects', 'sceneSchedule','dominantTrack', 'dominantObject','simulatedEBR');
mathieu@14 152 saveAnnotationTxt(sceneSchedule,outputPath,outputFileName);
mathieu@14 153
gregoire@19 154 w = sum(tracks,1);
gregoire@19 155 if norm %Normalize to [-norm,norm]
gregoire@19 156 w = w*norm/max(abs(w));
gregoire@19 157 end
gregoire@19 158
gregoire@19 159 audiowrite([outputPath 'sound/' outputFileName '_channel_mix' '.wav'],w,sr);
gregoire@19 160
gregoirelafay@17 161 switch channelOption
gregoire@19 162 case 1
gregoirelafay@17 163 if norm %Normalize to [-norm,norm]
gregoire@19 164 tracks = tracks*norm/max(abs(sum(tracks,1)));
gregoirelafay@17 165 end
gregoire@19 166 audiowrite([outputPath 'sound/' outputFileName '_channel_split' '.wav'],tracks',sr);
gregoirelafay@17 167 case 2
gregoire@19 168 if norm %Normalize to [-norm,norm]
gregoire@19 169 tracks = tracks*norm/max(abs(sum(tracks,1)));
gregoirelafay@17 170 end
gregoirelafay@17 171 for jj=1:size(tracks,1)
gregoire@19 172 audiowrite([outputPath 'sound/' outputFileName '_channel_' num2str(jj) '_class_' sceneObjects(jj).classLabel '.wav'],tracks(jj,:),sr);
gregoirelafay@17 173 end
gregoire@16 174 end
gregoire@19 175
gregoire@16 176
gregoire@16 177 if figuresOption
gregoire@16 178 settingFigure.cmap = generateColormap(sceneObjects);
gregoire@16 179 settingFigure.width=29.7; % cm
gregoire@16 180 settingFigure.height=21; % cm
gregoire@16 181 settingFigure.FontSize=16;
gregoire@16 182 settingFigure.sr=sr;
gregoire@16 183 settingFigure.sceneDuration=score.sceneDuration;
mathieu@14 184
gregoire@16 185 coloredSpectrumVisualization(tracks,1,settingFigure,figuresOption,[outputPath 'annotation/' outputFileName,'-spectrum.png']);
gregoire@16 186 timeDomainVisualization(tracks,2,settingFigure,figuresOption,[outputPath 'annotation/' outputFileName,'-timeDomain.png']);
gregoire@16 187 pianoRollVisualization(sceneObjects,sceneSchedule,score,3,settingFigure,figuresOption,[outputPath 'annotation/' outputFileName,'-pianoRoll.png'])
mathieu@14 188 end
mathieu@14 189 end