| mirfunction(method,x,varg,nout,specif,init,main) |
function o = mirfunction(method,x,varg,nout,specif,init,main)
% Meta function called by all MIRtoolbox functions.
% Integrates the function into the general flowchart
% and eventually launches the "mireval" evaluation process.
% Here are the successive steps in the following code:
% - If the input is an audio filename, instantiates a new design flowchart.
% - Reads all the options specified by the user.
% - Performs the 'init' part of the MIRtoolbox function:
% - If the input is a design flowchart,
% add the 'init' part in the flowchart.
% - If the input is some MIRtoolbox data,
% execute the 'init' part on that data.
% - Performs the 'main' part of the MIRtoolbox function.
if isempty(x)
o = {{},{},{}};
return
end
if ischar(x) % The input is a file name.
% Starting point of the design process
design_init = 1;
filename = x;
if strcmpi(func2str(method),'miraudio')
postoption = {};
else
postoption.mono = 1;
end
orig = mirdesign(@miraudio,'Design',{varg},postoption,struct,'miraudio');
% Implicitly, the audio file needs to be loaded first.
elseif isnumeric(x)
mirerror(func2str(method),'The input should be a file name or a MIRtoolbox object.');
else
design_init = 0;
orig = x;
end
% Reads all the options specified by the user.
[orig during after] = miroptions(method,orig,specif,varg);
% Performs the 'init' part of the MIRtoolbox function.
if isa(orig,'mirdesign')
if not(get(orig,'Eval'))
% Top-down construction of the general design flowchart
if isstruct(during) && isfield(during,'frame') && ...
isstruct(during.frame) && during.frame.auto
% 'Frame' option:
% Automatic insertion of the mirframe step in the design
orig = mirframe(orig,during.frame.length.val,...
during.frame.length.unit,...
during.frame.hop.val,...
during.frame.hop.unit);
end
% The 'init' part of the function can be integrated into the design
% flowchart. This leads to a top-down construction of the
% flowchart.
% Automatic development of the implicit prerequisites,
% with management of the data types throughout the design process.
[orig type] = init(orig,during);
o = mirdesign(method,orig,during,after,specif,type);
if design_init && not(strcmpi(filename,'Design'))
% Now the design flowchart has been completed created.
% If the 'Design' keyword not used,
% the function is immediately evaluated
o = mireval(o,filename,nout);
else
o = returndesign(o,nout);
end
if not(iscell(o))
o = {o};
end
return
else
% During the top-down traversal of the flowchart (evaleach), at the
% beginning of the evaluation process.
if not(isempty(get(orig,'TmpFile'))) && get(orig,'ChunkDecomposed')
orig = evaleach(orig);
if iscell(orig)
orig = orig{1};
end
x = orig;
else
[orig x] = evaleach(orig);
end
if not(isequal(method,@nthoutput))
if iscell(orig)
orig = orig{1};
end
if isempty(get(orig,'InterChunk'))
orig = set(orig,'InterChunk',get(x,'InterChunk'));
end
end
end
else
design = 0;
if iscell(orig)
i = 0;
while i<length(orig) && not(design)
i = i+1;
if isa(orig{i},'mirdesign')
design = i;
end
end
end
if design
% For function with multiple inputs
if design == 1 && not(get(orig{1},'Eval'))
% Progressive construction of the general design
[orig type] = init(orig,during);
o = mirdesign(method,orig,during,after,specif,type);
o = set(o,'Size',get(orig{1},'Size'));
o = returndesign(o,nout);
return
else
% Evaluation of the design.
% First top-down initiation (evaleach), then bottom-up process.
for io = 1:length(orig)
if isa(orig{io},'mirdesign')
o = evaleach(orig{io});
if iscell(o)
o = o{:};
end
orig{io} = o;
end
end
end
elseif not(isempty(init)) && not(isempty(during))
if isstruct(during) && isfield(during,'frame') && ...
isstruct(during.frame) && during.frame.auto
orig = mirframe(orig,during.frame.length,during.frame.hop);
end
% The input of the function is not a design flowchart, which
% the 'init' part of the function could be integrated into.
% (cf. previous call of 'init' in this script).
% For that reason, the 'init' part of the function needs to be
% evaluated now.
orig = init(orig,during);
end
end
% Performs the 'main' part of the MIRtoolbox function.
if not(iscell(orig) && not(ischar(orig{1}))) && ...
not(isa(orig,'mirdesign') || isa(orig,'mirdata'))
o = {orig};
return
end
filenamearg = orig;
if iscell(filenamearg) && not(ischar(filenamearg{1}))
filenamearg = filenamearg{1};
end
if iscell(filenamearg) && not(ischar(filenamearg{1}))
filenamearg = filenamearg{1};
end
filename = get(filenamearg,'Name');
if not(isempty(during)) && mirverbose
if length(filename) == 1
disp(['Computing ',func2str(method),' related to ',filename{1},'...'])
else
disp(['Computing ',func2str(method),' for all audio files ...'])
end
end
if iscell(x)
x1 = x{1};
else
x1 = x;
end
if not(iscell(orig) || isnumeric(x))
orig = set(orig,'Index',get(x1,'Index'));
end
if iscell(orig)
o = main(orig,during,after);
else
d = get(orig,'Data');
if isamir(orig,'miraudio') && ...
length(d) == 1 && length(d{1}) == 1 && isempty(d{1}{1})
% To solve a problem when MP3read returns empty chunk.
% Warning: it should not be a cell, because for instance nthoutput can have first input empty...
o = orig;
else
o = main(orig,during,after);
end
end
if not(iscell(o) && length(o)>1) || (isa(x,'mirdesign') && get(x,'Eval'))
o = {o x};
elseif iscell(x) && isa(x{1},'mirdesign') && get(x{1},'Eval')
o = {o x{1}};
elseif not(isempty(varg)) && isstruct(varg{1}) ...
&& not(iscell(o) && iscell(o{1}))
% When the function was called by mireval, the output should be packed
% into one single cell array (in order to be send back to calling
% routines).
o = {o};
end
function o = returndesign(i,nout)
o = cell(1,nout);
o{1} = i;
for k = 2:nout
o{k} = nthoutput(i,k);
end
|
|