annotate nonExposed/generateScene.m @ 19:8d33767e070a

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