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