Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/@mirdesign/evaleach.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/MIRToolbox/@mirdesign/evaleach.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,986 @@ +function [y d2] = evaleach(d,single,name) +% Top-down traversal of the design flowchart, at the beginning of the +% evaluation phase. +% Called by mirfunction, mireval, mirframe and mirsegment. +% This is during that traversal that we check whether a chunk decomposition +% needs to be performed or not, and carry out that chunk decomposition. + +if nargin<3 || isempty(name) + if not(ischar(d.method)) + name = func2str(d.method); + end +end +if nargin<2 + single = 0; +end + +CHUNKLIM = mirchunklim; +f = d.file; +fr = d.frame; +frnochunk = isfield(d.frame,'dontchunk'); +frchunkbefore = isfield(d.frame,'chunkbefore'); +sg = d.segment; +sr = d.sampling; +sr2 = d.resampling; +w = d.size; +lsz = w(2)-w(1)+1; +len = lsz/sr; +if ischar(sg) + error('ERROR in MIREVAL: mirsegment of design object accepts only array of numbers as second argument.'); +end +if not(isempty(sg)) + over = find(sg(2,:) > len); + if not(isempty(over)) + sg = sg(:,1:over-1); + end +end +a = d.argin; +ch = d.chunk; +chan = d.channel; +specif = d.specif; +if isaverage(specif) + specif.eachchunk = 'Normal'; +end + +if ischar(a) + % The top-down traversal of the design flowchart now reaches the lowest + % layer, i.e., audio file loading. + % Now the actual evaluation will be carried out bottom-up. + + if isempty(ch) + % No chunk decomposition + y = miraudio(f,'Now',[w(:)' 0 chan]); + else + % Chunk decomposition + y = miraudio(f,'Now',[ch(1),ch(2) 0 chan]); + end + if not(isempty(d.postoption)) && d.postoption.mono + y = miraudio(y,'Mono',1); + end + y = set(y,'AcrossChunks',get(d,'AcrossChunks')); + d2 = d; + +elseif d.chunkdecomposed && isempty(d.tmpfile) + % Already in a chunk decomposition process + + [y d2] = evalnow(d); + +elseif isempty(fr) || frnochunk || not(isempty(sg)) %% WHAT ABOUT CHANNELS? + % No frame or segment decomposition in the design to evaluate + % (Or particular frame decomposition, where chunks are not distributed to children (frnochunk).) + + if not(isfield(specif,'eachchunk')) ... + || d.nochunk ... + || (not(isempty(single)) && isnumeric(single) && single > 1 ... + && isfield(specif,'combinechunk') ... + && iscell(specif.combinechunk)) + chunks = []; + elseif not(isempty(sg)) + meth = 'Segment '; + if size(sg,1) == 1 + chunks = floor(sg(1:end-1)*sr)+1; + chunks(2,:) = min( floor(sg(2:end)*sr)-1,lsz-1)+1; + else + chunks = floor(sg*sr); + chunks(1,:) = chunks(1,:)+1; + end + else + meth = 'Chunk '; + if isempty(fr) + if lsz > CHUNKLIM + % The required memory exceed the max memory threshold. + nch = ceil(lsz/CHUNKLIM); + %%% TAKE INTO CONSIDERATION NUMBER OF CHANNELS; ETC... + chunks = max(0,lsz-CHUNKLIM*(nch:-1:1))+w(1); + chunks(2,:) = lsz-CHUNKLIM*(nch-1:-1:0)+w(1)-1; + else + chunks = []; + end + else + chunks = compute_frames(fr,sr,sr2,w,lsz,CHUNKLIM,d.overlap); + end + end + + if not(isempty(chunks)) + % The chunk decomposition is performed. + nch = size(chunks,2); + d = callbeforechunk(d,d,w,lsz); % Some optional initialisation + tmp = []; + if mirwaitbar + h = waitbar(0,['Computing ' name]); + else + h = 0; + end + if not(isempty(d.tmpfile)) && d.tmpfile.fid == 0 + % When applicable, a new temporary file is created. + d.tmpfile.fid = fopen('tmpfile.mirtoolbox','w'); + end + tmpfile = []; + if not(d.ascending) + chunks = fliplr(chunks); + end + + afterpostoption = d.postoption; % Used only when: + % - eachchunk is set to 'Normal', + % - combinechunk is not set to 'Average', and + % - no afterchunk field has been specified. + % afterpostoption will be used for the final call + % to the method after the chunk decomposition. + method = d.method; + if ischar(specif.eachchunk) && strcmpi(specif.eachchunk,'Normal') + if not(isempty(d.postoption)) + pof = fieldnames(d.postoption); + for o = 1:length(pof) + if isfield(specif.option.(pof{o}),'chunkcombine') + afterpostoption = rmfield(afterpostoption,pof{o}); + else + d.postoption = rmfield(d.postoption,pof{o}); + end + end + end + else + method = specif.eachchunk; + end + + d2 = d; + d2.method = method; + y = {}; + for i = 1:size(chunks,2) + disp([meth,num2str(i),'/',num2str(nch),'...']) + d2 = set(d2,'Chunk',[chunks(1,i) chunks(2,i) (i == size(chunks,2))]); + + if not(ischar(specif.eachchunk) && ... + strcmpi(specif.eachchunk,'Normal')) + if frnochunk + d2.postoption = 0; + else + diffchunks = diff(chunks); % Usual chunk size + d2.postoption = max(diffchunks) - diffchunks(i); + % Reduction of the current chunk size to be taken into + % consideration in mirspectrum, for instance, using + % zeropadding + end + end + + d2 = set(d2,'InterChunk',tmp); + d2.chunkdecomposed = 1; + + [ss d3] = evalnow(d2); + + if iscell(ss) && not(isempty(ss)) + tmp = get(ss{1},'InterChunk'); + elseif isstruct(ss) + tmp = []; + else + tmp = get(ss,'InterChunk'); + end + + % d2 is like d3 except that its argument is now evaluated. + d3.postoption = d.postoption; % Pas joli joli + d3.method = method; + d2 = d3; % This new argument is transfered to d + + y = combinechunk_noframe(y,ss,sg,i,d2,chunks,single); + + clear ss + if h + if not(d.ascending) + close(h) + h = waitbar((chunks(1,i)-chunks(1,end))/chunks(2,1),... + ['Computing ' func2str(d.method) ' (backward)']); + else + waitbar((chunks(2,i)-chunks(1))/chunks(end),h) + end + end + end + + y = afterchunk_noframe(y,lsz,d,afterpostoption,d2); + % Final operations to be executed after the chunk decomposition + + if isa(d,'mirstruct') && ... + (isempty(d.frame) || isfield(d.frame,'dontchunk')) + y = evalbranches(d,y); + end + if h + close(h) + end + drawnow + + else + % No chunk decomposition + [y d2] = evalnow(d); + if isa(d,'mirstruct') && isfield(d.frame,'dontchunk') + y = evalbranches(d,y); + end + end +elseif d.nochunk + [y d2] = evalnow(d); +else + % Frame decomposition in the design to be evaluated. + chunks = compute_frames(fr,sr,sr2,w,lsz,CHUNKLIM,d.overlap); + if size(chunks,2)>1 + % The chunk decomposition is performed. + if mirwaitbar + h = waitbar(0,['Computing ' name]); + else + h = 0; + end + inter = []; + d = set(d,'FrameDecomposition',1); + d2 = d; + nch = size(chunks,2); + y = {}; + + if frchunkbefore + d2after = d2; + d2.method = d2.argin.method; + d2.option = d2.argin.option; + d2.postoption = d2.argin.postoption; + d2.argin = d2.argin.argin; + end + + for fri = 1:nch % For each chunk... + disp(['Chunk ',num2str(fri),'/',num2str(nch),'...']) + d2 = set(d2,'Chunk',chunks(:,fri)'); + d2 = set(d2,'InterChunk',inter); + %d2.postoption = []; + [res d2] = evalnow(d2); + if not(isempty(res)) + if iscell(res) + inter = get(res{1},'InterChunk'); + elseif not(isstruct(res)) + inter = get(res,'InterChunk'); + res = {res}; + end + end + + y = combinechunk_frame(y,res,d2,fri); + if h + waitbar(chunks(2,fri)/chunks(end),h); + end + end + + if frchunkbefore + y = d2after.method(y,d2after.option,d2after.postoption); + end + + if isa(d,'mirstruct') && get(d,'Stat') + y = mirstat(y); + end + if h + close(h) + end + else + % No chunk decomposition + [y d2] = evalnow(d); + end +end + + +if iscell(y) + for i = 1:length(y) + if not(isempty(y{i}) || isstruct(y{i})) + if iscell(y{i}) + for j = 1:length(y{i}) + y{i}{j} = set(y{i}{j},'InterChunk',[]); + end + else + y{i} = set(y{i},'InterChunk',[]); + end + end + end +end + + +function chunks = compute_frames(fr,sr,sr2,w,lsz,CHUNKLIM,frov) +if strcmpi(fr.length.unit,'s') + fl = fr.length.val*sr; + fl2 = fr.length.val*sr2; +elseif strcmpi(fr.length.unit,'sp') + fl = fr.length.val; + fl2 = fl; +end +if strcmpi(fr.hop.unit,'/1') + h = fr.hop.val*fl; + h2 = fr.hop.val*fl2; +elseif strcmpi(fr.hop.unit,'%') + h = fr.hop.val*fl*.01; + h2 = fr.hop.val*fl2*.01; +elseif strcmpi(fr.hop.unit,'s') + h = fr.hop.val*sr; + h2 = fr.hop.val*sr2; +elseif strcmpi(fr.hop.unit,'sp') + h = fr.hop.val; + h2 = fr.hop.val; +elseif strcmpi(fr.hop.unit,'Hz') + h = sr/fr.hop.val; + h2 = sr2/fr.hop.val; +end +n = floor((lsz-fl)/h)+1; % Number of frames +if n < 1 + %warning('WARNING IN MIRFRAME: Frame length longer than total sequence size. No frame decomposition.'); + fp = w; + fp2 = (w-1)/sr*sr2+1; +else + st = floor(((1:n)-1)*h)+w(1); + st2 = floor(((1:n)-1)*h2)+w(1); + fp = [st; floor(st+fl-1)]; + fp(:,fp(2,:)>w(2)) = []; + fp2 = [st2; floor(st2+fl2-1)]; + fp2(:,fp2(2,:)>(w(2)-w(1))/sr*sr2+w(2)) = []; +end +fpe = (fp2-1)/sr2-(fp-1)/sr; %Rounding error if resampling +fpsz = (fp(2,1)-fp(1,1)) * n; % Total number of samples +fpsz2 = (fp2(2,1)-fp2(1,1)) * n; % Total number of samples +if max(fpsz,fpsz2) > CHUNKLIM + % The required memory exceed the max memory threshold. + nfr = size(fp,2); % Total number of frames + frch = max(ceil(CHUNKLIM/(fp(2,1)-fp(1,1))),2); % Number of frames per chunk + frch = max(frch,frov*2); + [unused cut] = min(abs(fpe(1,frch:-1:1))); + %frch = frch - cut; + % this correspond to the frame with less rounding error + nch = ceil((nfr-frch)/(frch-frov))+1; % Number of chunks + chbeg = (frch-frov)*(0:nch-1)+1; % First frame in the chunk + chend = (frch-frov)*(0:nch-1)+frch; % Last frame in the chunk + chend = min(chend,nfr); + if frov > 1 + chbeg = chend-frch+1; + end + chunks = [fp(1,chbeg) ; fp(2,chend)+1]; % After resampling, one sample may be missing, leading to a complete frame drop. + chunks(end) = min(chunks(end),fp(end)); % Last chunk should not extend beyond audio size. +else + chunks = []; +end + + +function res = combinechunk_frame(old,new,d2,fri) +if isempty(mirgetdata(new)) + res = old; + return +end +if isstruct(old) + f = fields(old); + for i = 1:length(f) + res.(f{i}) = combinechunk_frame(old.(f{i}),new.(f{i}),d2,fri); + end + return +end +if fri == 1 + res = new; +elseif isfield(d2,'specif') && isfield(d2.specif,'combineframes') + res = d2.specif.combineframes(old{1},new{1}); +else + res = combineframes(old,new); +end + + +function res = combinechunk_noframe(old,new,sg,i,d2,chunks,single) +if isempty(new) + res = {}; + return +end +if isempty(mirgetdata(new)) + res = old; + return +end +if not(iscell(new)) + new = {new}; +end +if not(iscell(old)) + old = {old}; +end +if not(isempty(old)) && isstruct(old{1}) + f = fields(old{1}); + for j = 1:length(f) + index.type = '.'; + index.subs = f{j}; + res.(f{j}) = combinechunk_noframe(old{1}.(f{j}),new{1}.(f{j}),... + sg,i,subsref(d2,index),chunks,single); + end + return +end +if ischar(single) && not(isempty(old)) + old = {old{1}}; +end +if isempty(sg) + if isaverage(d2.specif) + % Measure total size for later averaging + if iscell(new) + new1 = new{1}; + else + new1 = new; + end + dnew = get(new1,'Data'); + dnew = mircompute(@multweight,dnew,chunks(2,i)-chunks(1,i)+1); + if iscell(new) + new{1} = set(new1,'Data',dnew); + else + new = set(new1,'Data',dnew); + end + end + %tmp = get(new{1},'InterChunk'); + if not(isempty(d2.tmpfile)) && d2.tmpfile.fid > 0 + % If temporary file is used, chunk results are written + % in the file + if i < size(chunks,2) + ds = get(new{1},'Data'); + ps = get(new{1},'Pos'); + % ftell(d2.tmpfile.fid) + count = fwrite(d2.tmpfile.fid,ds{1}{1},'double'); + count = fwrite(d2.tmpfile.fid,ps{1}{1},'double'); + % ftell(d2.tmpfile.fid) + clear ds ps + end + res = new; + else + % Else, chunk results are directly combined in active + % memory + if i == 1 + res = new; + else + if isfield(d2.specif,'combinechunk') + if not(iscell(d2.specif.combinechunk)) + method = {d2.specif.combinechunk}; + else + method = d2.specif.combinechunk; + end + for z = 1:length(old) + if isframed(old{z}) + res(z) = combineframes(old{z},new{z}); + elseif ischar(method{z}) + if strcmpi(method{z},'Concat') + res{z} = concatchunk(old{z},new{z},d2.ascending); + elseif strcmpi(method{z},'Average') + res{z} = sumchunk(old{z},new{z}); + else + error(['SYNTAX ERROR: ',... + method{z},... + ' is not a known keyword for combinechunk.']); + end + else + res{z} = method{z}(old{z},new{z}); + end + end + else + for z = 1:length(old) + if isframed(old{z}) + res(z) = combineframes(old{z},new{z}); + else + mirerror('MIREVAL','Chunk recombination in non-framed mode is not available for all features yet. Please turn off the chunk decomposition.'); + end + end + end + end + end +else + if i == 1 + res = new; + else + for z = 1:length(old) + res{z} = combinesegment(old{z},new{z}); + end + end +end + + +function res = afterchunk_noframe(input,lsz,d,afterpostoption,d2) +if isstruct(input) + %mirerror('MIREVAL','Sorry, mirstruct only accepts frame-decomposed objects as ''tmp'' fields.'); + res = input; + %f = fields(input); + %for i = 1:length(f) + % index.type = '.'; + % index.subs = f{i}; + % res.(f{i}) = afterchunk_noframe(input.(f{i}),lsz,... + % subsref(d,index),afterpostoption,subsref(d2,index)); + %end + return +end +if isfield(d2.specif,'afterchunk') + res{1} = d2.specif.afterchunk(input{1},lsz,d.postoption); +elseif isaverage(d2.specif) + res{1} = divideweightchunk(input{1},lsz); +elseif not(isempty(afterpostoption)) && isempty(d2.tmpfile) + res{1} = d.method(input{1},[],afterpostoption); +else + res = input; +end +if not(isempty(d2.tmpfile)) + adr = ftell(d2.tmpfile.fid); + fclose(d2.tmpfile.fid); + ytmpfile.fid = fopen('tmpfile.mirtoolbox'); + fseek(ytmpfile.fid,adr,'bof'); + ytmpfile.data = input{1}; + ytmpfile.layer = 0; + res{1} = set(input{1},'TmpFile',ytmpfile); +end + + +function old = combineframes(old,new) +if not(iscell(old)) + old = {old}; +end +if not(iscell(new)) + new = {new}; +end +for var = 1:length(new) + ov = old{var}; + nv = new{var}; + if isa(ov,'mirscalar') + ov = combinedata(ov,nv,'Data'); + ov = combinedata(ov,nv,'Mode'); + if isa(ov,'mirpitch') + ov = combinedata(ov,nv,'Amplitude'); + end + else + if isa(ov,'mirtemporal') + [ov omatch nmatch] = combinedata(ov,nv,'Time',[],[],@modiftime); + else + [ov omatch nmatch] = combinedata(ov,nv,'Pos',[],[]); + if isa(ov,'mirspectrum') + [ov omatch nmatch] = combinedata(ov,nv,'Phase',[],[]); + end + end + ov = combinedata(ov,nv,'Data',omatch,nmatch); + end + ov = combinedata(ov,nv,'FramePos'); + ov = combinedata(ov,nv,'PeakPos'); + ov = combinedata(ov,nv,'PeakVal'); + ov = combinedata(ov,nv,'PeakMode'); + old{var} = ov; +end + + +function [ov omatch nmatch] = combinedata(ov,nv,key,omatch,nmatch,modifdata) +if isstruct(ov) + omatch = []; + nmatch = []; + f = fields(ov); + for i = 1:length(f) + ov.(f{i}) = combinedata(ov.(f{i}),nv.(f{i}),key); + end + return +end +odata = get(ov,key); +if isempty(odata) || isempty(odata{1}) + return +end +odata = odata{1}; +if iscell(odata) + if ischar(odata{1}) + return + else + odata = odata{1}; + end +end +ndata = get(nv,key); +ndata = ndata{1}; +if iscell(ndata) + ndata = ndata{1}; +end +if nargin>3 + if isempty(omatch) + ol = size(odata,1); + nl = size(ndata,1); + unmatch = ol-nl; + if unmatch>0 + [unused idx] = min(odata(1:1+unmatch,1,1)-ndata(1)); + omatch = idx:idx+nl-1; + nmatch = 1:nl; + elseif unmatch<0 + [unused idx] = min(ndata(1:1-unmatch,1,1)-odata(1)); + nmatch = idx:idx+ol-1; + omatch = 1:ol; + else + nmatch = 1:nl; + omatch = 1:ol; + end + end + odata(omatch,end+1:end+size(ndata,2),:,:) = ndata(nmatch,:,:,:); %4.D for keysom +else + odata(:,end+1:end+size(ndata,2),:,:) = ndata; +end +ov = set(ov,key,{{odata}}); %{odata} for warped chromagram for instance.... + + +function d = modiftime(d,p) +d = d + p; + + +function [y d] = evalnow(d) +% Go one step further in the top-down evaluation initialisation +argin = d.argin; +if not(iscell(argin)) + argin = {argin}; +end +for i = 1:length(argin) + a = argin{i}; + if not(d.ascending) + a.ascending = 0; + end + if isa(a,'mirdata') + % Input already computed + tmpfile = get(a,'TmpFile'); + if not(isempty(tmpfile)) && tmpfile.fid > 0 + % The input can be read from the temporary file + ch = get(d,'Chunk'); + a = tmpfile.data; + a = set(a,'InterChunk',get(d,'InterChunk'),'TmpFile',tmpfile); + channels = get(a,'Channels'); + channels = length(channels{1}); + if not(channels) + channels = 1; + end + size = (ch(2)-ch(1)+1); + current = ftell(tmpfile.fid); + fseek(tmpfile.fid,current-size*(channels+1)*8,'bof'); + %ftell(tmpfile.fid) + [data count] = fread(tmpfile.fid,[size,channels],'double'); + %count + data = reshape(data,[size,1,channels]); + [pos count] = fread(tmpfile.fid,size,'double'); + %count + % ftell(tmpfile.fid) + fseek(tmpfile.fid,current-size*(channels+1)*8,'bof'); + a = set(a,'Data',{{data}},'Pos',{{pos}}); + if ch(3) + fclose(tmpfile.fid); + delete('tmpfile.mirtoolbox'); + end + argin{i} = a; + end + elseif isa(a,'mirdesign') + if isempty(a.stored) + % The design parameters are transfered to the previous component + % in the design process + a.size = d.size; + a.chunk = d.chunk; + a.file = d.file; + a.channel = d.channel; + a.eval = 1; + a.interchunk = d.interchunk; + a.sampling = d.sampling; + if isstruct(d.frame) && isfield(d.frame,'decomposition') ... + && not(isempty(d.frame.decomposition)) + a.chunkdecomposed = 1; + else + a.chunkdecomposed = d.chunkdecomposed; + end + if not(isempty(d.frame)) && ... + not(strcmp(func2str(d.method),'mirframe')) + a.frame = d.frame; + end + a.ready = 1; + a.acrosschunks = d.acrosschunks; + a.index = d.index; + argin{i} = a; + else + % Variable already calculated + tmp = get(d,'Struct'); + if not(isempty(tmp)) + for j = 1:length(a.stored) % (if modified, modify also mirframe) + stored = a.stored{j}; + if iscell(stored) + if length(stored)>1 + tmp = tmp{stored{1},stored{2}}; + else + tmp = tmp{stored{1}}; + end + else + tmp = getfield(tmp,stored); + end + end + if iscell(tmp) + tmp = tmp{1}; + end + else + mirerror('evaleach','THERE is a problem..'); + end + argin{i} = tmp; + end + end +end +if not(iscell(d.argin)) + argin = argin{1}; +end +d.option.struct = get(d,'Struct'); +if iscell(d.postoption) + [y argin] = d.method(argin,d.option,d.postoption{:}); +else + [y argin] = d.method(argin,d.option,d.postoption); +end +d = set(d,'Argin',argin); +if isa(d,'mirstruct') && not(isfield(d.frame,'dontchunk')) && isempty(get(d,'Chunk')) + y = evalbranches(d,y); +end + + +function z = evalbranches(d,y) +% For complex flowcharts, now that the first temporary variable (y) has been +% computed, the dependent features (d) should be evaluated as well. +branch = get(d,'Data'); + +for i = 1:length(branch) + if isa(branch{i},'mirdesign') && get(branch{i},'NoChunk') == 1 + % if the value is 2, it is OK. + %mirerror('mireval','Flowchart badly designed: mirstruct should not be used if one or several final variables do not accept chunk decomposition.'); + end +end + +fields = get(d,'Fields'); +z = struct; +tmp = get(d,'Tmp'); +for i = 1:length(branch) + z.(fields{i}) = evalbranch(branch{i},tmp,y); +end +if get(d,'Stat') && isempty(get(d,'Chunk')) + z = mirstat(z,'FileNames',0); +end + + +function b = evalbranch(b,d,y) +% We need to evaluate the branch reaching the current node (b) from the parent +% corresponding to the temporary variable (d), + +if iscell(b) + mirerror('MIREVAL','Sorry, forked branching of temporary variable cannnot be evaluated in current version of MIRtoolbox.'); +end +if isstruct(b) + % Subtrees are evaluated branch after branch. + f = fields(b); + for i = 1:length(f) + b.(f{i}) = evalbranch(b.(f{i}),d,y); + end + return +end +if isequal(b,d) + %% Does it happen ever?? + b = y; + return +end +if not(isa(b,'mirdesign')) + mirerror('MIRSTRUCT','In the mirstruct object you defined, the final output should only depend on ''tmp'' variables, and should not therefore reuse the ''Design'' keyword.'); +end +v = get(b,'Stored'); +if length(v)>1 && ischar(v{2}) + % + f = fields(d); + for i = 1:length(f) + if strcmpi(v{2},f) + b = y; % OK, now the temporary variable has been found. + % End of recursion. + return + end + end +end + +argin = evalbranch(get(b,'Argin'),d,y); % Recursion one parent up + +% The operation corresponding to the branch from the parent to the node +% is finally evaluated. +if iscell(b.postoption) + b = b.method(argin,b.option,b.postoption{:}); +else + b = b.method(argin,b.option,b.postoption); +end + + +function res = isaverage(specif) +res = isfield(specif,'combinechunk') && ... + ((ischar(specif.combinechunk) && ... + strcmpi(specif.combinechunk,'Average')) || ... + (iscell(specif.combinechunk) && ... + ischar(specif.combinechunk{1}) && ... + strcmpi(specif.combinechunk{1},'Average'))); + + +function d0 = callbeforechunk(d0,d,w,lsz) +% If necessary, the chunk decomposition is performed a first time for +% initialisation purposes. +% Currently used only for miraudio(...,'Normal') +if not(ischar(d)) && not(iscell(d)) + specif = d.specif; + CHUNKLIM = mirchunklim; + nch = ceil(lsz/CHUNKLIM); + if isfield(specif,'beforechunk') ... + && ((isfield(d.option,specif.beforechunk{2}) ... + && d.option.(specif.beforechunk{2})) ... + || (isfield(d.postoption,specif.beforechunk{2}) ... + && d.postoption.(specif.beforechunk{2})) ) + if mirwaitbar + h = waitbar(0,['Preparing ' func2str(d.method)]); + else + h = 0; + end + for i = 1:nch + disp(['Chunk ',num2str(i),'/',num2str(nch),'...']) + chbeg = CHUNKLIM*(i-1); + chend = CHUNKLIM*i-1; + d2 = set(d,'Size',d0.size,'File',d0.file,... + 'Chunk',[chbeg+w(1) min(chend,lsz-1)+w(1)]); + d2.method = specif.beforechunk{1}; + d2.postoption = {chend-lsz}; + d2.chunkdecomposed = 1; + [tmp d] = evalnow(d2); + d0 = set(d0,'AcrossChunks',tmp); + if h + waitbar(chend/lsz,h) + end + end + if h + close(h); + end + drawnow + else + d0 = callbeforechunk(d0,d.argin,w,lsz); + end +end + + +function y = concatchunk(old,new,ascending) +do = get(old,'Data'); +dn = get(new,'Data'); +fpo = get(old,'FramePos'); +fpn = get(new,'FramePos'); +if isa(old,'mirscalar') + y = set(old,'Data',{{[do{1}{1},dn{1}{1}]}},... + 'FramePos',{{[fpo{1}{1},fpn{1}{1}]}}); +else + to = get(old,'Pos'); + tn = get(new,'Pos'); + if ascending + y = set(old,'Data',{{[do{1}{1};dn{1}{1}]}},... + 'Pos',{{[to{1}{1};tn{1}{1}]}},... + 'FramePos',{{[fpo{1}{1},fpn{1}{1}]}}); + else + y = set(old,'Data',{{[dn{1}{1};do{1}{1}]}},... + 'Pos',{{[tn{1}{1};to{1}{1}]}},... + 'FramePos',{{[fpo{1}{1},fpn{1}{1}]}}); + end +end + + +function y = combinesegment(old,new) +do = get(old,'Data'); +to = get(old,'Pos'); +fpo = get(old,'FramePos'); +ppo = get(old,'PeakPos'); +pppo = get(old,'PeakPrecisePos'); +pvo = get(old,'PeakVal'); +ppvo = get(old,'PeakPreciseVal'); +pmo = get(old,'PeakMode'); +apo = get(old,'AttackPos'); +rpo = get(old,'ReleasePos'); +tpo = get(old,'TrackPos'); +tvo = get(old,'TrackVal'); + +dn = get(new,'Data'); +tn = get(new,'Pos'); +fpn = get(new,'FramePos'); +ppn = get(new,'PeakPos'); +pppn = get(new,'PeakPrecisePos'); +pvn = get(new,'PeakVal'); +ppvn = get(new,'PeakPreciseVal'); +pmn = get(new,'PeakMode'); +apn = get(new,'AttackPos'); +rpn = get(new,'ReleasePos'); +tpn = get(new,'TrackPos'); +tvn = get(new,'TrackVal'); + +if not(isempty(do)) + y = set(old,'Data',{{do{1}{:},dn{1}{:}}}); +end + +y = set(old,'FramePos',{{fpo{1}{:},fpn{1}{:}}}); + +if not(isempty(to)) && size(do{1},2) == size(to{1},2) + y = set(y,'Pos',{{to{1}{:},tn{1}{:}}}); +end + +if not(isempty(ppo)) + y = set(y,'PeakPos',{{ppo{1}{:},ppn{1}{:}}},... + 'PeakVal',{{pvo{1}{:},pvn{1}{:}}},... + 'PeakMode',{{pmo{1}{:},pmn{1}{:}}}); +end + +if not(isempty(pppn)) + y = set(y,'PeakPrecisePos',{[pppo{1},pppn{1}{1}]},... + 'PeakPreciseVal',{[ppvo{1},ppvn{1}{1}]}); +end + +if not(isempty(apn)) + y = set(y,'AttackPos',{[apo{1},apn{1}{1}]}); +end + +if not(isempty(rpn)) + y = set(y,'ReleasePos',{[rpo{1},rpn{1}{1}]}); +end + +if not(isempty(tpn)) + y = set(y,'TrackPos',{[tpo{1},tpn{1}{1}]}); +end + +if not(isempty(tvn)) + y = set(y,'TrackVal',{[tvo{1},tvn{1}{1}]}); +end + +if isa(old,'miremotion') + deo = get(old,'DimData'); + ceo = get(old,'ClassData'); + den = get(new,'DimData'); + cen = get(new,'ClassData'); + afo = get(old,'ActivityFactors'); + vfo = get(old,'ValenceFactors'); + tfo = get(old,'TensionFactors'); + hfo = get(old,'HappyFactors'); + sfo = get(old,'SadFactors'); + tdo = get(old,'TenderFactors'); + ago = get(old,'AngerFactors'); + ffo = get(old,'FearFactors'); + afn = get(new,'ActivityFactors'); + vfn = get(new,'ValenceFactors'); + tfn = get(new,'TensionFactors'); + hfn = get(new,'HappyFactors'); + sfn = get(new,'SadFactors'); + tdn = get(new,'TenderFactors'); + agn = get(new,'AngerFactors'); + ffn = get(new,'FearFactors'); + y = set(y,'DimData',{[deo{1},den{1}{1}]},... + 'ClassData',{[ceo{1},cen{1}{1}]},... + 'ActivityFactors',{[afo{1},afn{1}{1}]},... + 'ValenceFactors',{[vfo{1},vfn{1}{1}]},... + 'TensionFactors',{[tfo{1},tfn{1}{1}]},... + 'HappyFactors',{[hfo{1},hfn{1}{1}]},... + 'SadFactors',{[sfo{1},sfn{1}{1}]},... + 'TenderFactors',{[tdo{1},tdn{1}{1}]},... + 'AngerFactors',{[ago{1},agn{1}{1}]},... + 'FearFactors',{[ffo{1},ffn{1}{1}]}... + ); +end + + +function y = sumchunk(old,new,order) +%do = mirgetdata(old); +%dn = mirgetdata(new); +do = get(old,'Data'); +do = do{1}{1}; +dn = get(new,'Data'); +dn = dn{1}{1}; +y = set(old,'ChunkData',do+dn); + + +function y = divideweightchunk(orig,length) +d = get(orig,'Data'); +if isempty(d) + y = orig; +else + v = mircompute(@divideweight,d,length); + y = set(orig,'Data',v); +end + +function e = multweight(d,length) +e = d*length; + +function e = divideweight(d,length) +e = d/length; \ No newline at end of file