Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirframe.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/mirframe.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,241 @@ +function [f x] = mirframe(x,varargin) +% f = mirframe(x) creates the frame decomposition of the audio signal x. +% (x can be a file name as well.) +% Optional arguments: +% mirframe(x,'Length',w,wu): +% w is the length of the window in seconds (default: .05 seconds) +% u is the unit, either +% 's' (seconds, default unit) +% or 'sp' (number of samples) +% mirframe(x,'Hop',h,hu): +% h is the hop factor, or distance between successive frames +% (default: half overlapping: each frame begins at the middle +% of the previous frame) +% u is the unit, either +% '/1' (ratio with respect to the frame length, default unit) +% '%' (ratio as percentage) +% 's' (seconds) +% 'sp' (number of samples) +% or 'Hz' (hertz), i.e., number of frames per second: the +% exactness of the frame rate is ensured and may cause a +% slight fluctuation of the elementary hop distances. +% These arguments can also be written as follows: +% mirframe(x,w,wu,h,hu) +% (where some of these parameters can be omitted). + +if isempty(x) + f = {}; + return +end +if iscell(x) + x = x{1}; +end +if nargin == 0 + f = miraudio; +elseif isa(x,'mirdesign') + if not(get(x,'Eval')) + % During bottom-up construction of the general design + + para = scanargin(varargin); + type = get(x,'Type'); + f = mirdesign(@mirframe,x,para,{},struct,type); + + fl = get(x,'FrameLength'); + fh = get(x,'FrameHop'); + flu = get(x,'FrameLengthUnit'); + fhu = get(x,'FrameHopUnit'); + if fl + f = set(f,'FrameLength',fl,'FrameLengthUnit',flu,... + 'FrameHop',fh,'FrameHopUnit',fhu); + else + f = set(f,'FrameLength',para.wlength.val,... + 'FrameLengthUnit',para.wlength.unit,... + 'FrameHop',para.hop.val,... + 'FrameHopUnit',para.hop.unit); + end + f = set(f,'FrameEval',1,... + 'SeparateChannels',get(x,'SeparateChannels')); + if not(isamir(x,'miraudio')) + f = set(f,'NoChunk',1); + end + else + % During top-down evaluation initiation + + if isstruct(varargin{1}) && isfield(varargin{1},'struct') + tmp = varargin{1}.struct; + x = set(x,'Struct',tmp); + varargin{1} = rmfield(varargin{1},'struct'); + end + e = evaleach(x); + if iscell(e) + e = e{1}; + end + if isempty(mirgetdata(e)) + f = e; + else + f = mirframe(e,varargin{:}); + end + end +elseif isa(x,'mirdata') + if isframed(x) + warning('WARNING IN MIRFRAME: The input data is already decomposed into frames. No more frame decomposition.'); + f = x; + else + x = purgedata(x); + dx = get(x,'Data'); + if isa(x,'mirtemporal') + dt = get(x,'Time'); + else + dt = get(x,'FramePos'); + end + sf = get(x,'Sampling'); + para = scanargin(varargin); + dx2 = cell(1,length(dx)); % magnitude in framed structure + dt2 = cell(1,length(dx)); % time positions in framed structure + fp = cell(1,length(dx)); % frame positions + for k = 1:length(dx) % For each audio file, ... + dxk = dx{k}; + dtk = dt{k}; + if strcmpi(para.wlength.unit,'s') + l = para.wlength.val*sf{k}; + elseif strcmpi(para.wlength.unit,'sp') + l = para.wlength.val; + end + if strcmpi(para.hop.unit,'/1') + h = para.hop.val*l; + elseif strcmpi(para.hop.unit,'%') + h = para.hop.val*l*.01; + elseif strcmpi(para.hop.unit,'s') + h = para.hop.val*sf{k}; + elseif strcmpi(para.hop.unit,'sp') + h = para.hop.val; + elseif strcmpi(para.hop.unit,'Hz') + h = sf{k}/para.hop.val; + end + l = floor(l); + dx2k = cell(1,length(dxk)); + dt2k = cell(1,length(dxk)); + fpk = cell(1,length(dxk)); + for j = 1:length(dxk) % For each segment, ... + dxj = dxk{j}; + dtj = dtk{j}; + if not(isa(x,'mirtemporal')) + dxj = dxj'; + dtj = dtj(1,:)'; + end + + n = floor((size(dxj,1)-l)/h)+1; % Number of frames + dx2j = zeros(l,n,size(dxj,3)); + dt2j = zeros(l,n); + fpj = zeros(2,n); + if n < 1 + disp('Frame length longer than total sequence size. No frame decomposition.'); + dx2j = dxj(:,1,:); + dt2j = dtj; + fpj = [dtj(1) ; dtj(end)]; + else + for i = 1:n % For each frame, ... + st = floor((i-1)*h+1); + stend = st+l-1; + dx2j(:,i,:) = dxj(st:stend,1,:); + dt2j(:,i) = dtj(st:stend); + fpj(:,i) = [dtj(st) dtj(stend)]; + end + end + dx2k{j} = dx2j; + dt2k{j} = dt2j; + fpk{j} = fpj; + end + dx2{k} = dx2k; + dt2{k} = dt2k; + fp{k} = fpk; + end + if isa(x,'mirtemporal') + f = set(x,'Time',dt2,'Data',dx2,'FramePos',fp); + else + f = mirtemporal([],'Time',dt2,'Data',dx2,'FramePos',fp,... + 'Sampling',get(x,'Sampling'),'Name',get(x,'Name'),... + 'Label',get(x,'Label'),'Channels',get(x,'Channels'),... + 'Centered',0,'Title',get(x,'Title')); + end + end +else + f = mirframe(miraudio(x),varargin{:}); +end + + +function para = scanargin(v) +if not(isempty(v)) && isstruct(v{1}) + if length(v) == 1 + para = v{1}; + else + para.wlength = v{1}; + para.hop = v{2}; + end + return +end +para.wlength.val = 0.05; +para.wlength.unit = 's'; +para.hop.val = 0.5; +para.hop.unit = '/1'; +nv = length(v); +i = 1; +j = 1; +while i <= nv + arg = v{i}; + if strcmpi(arg,'WinLength') || strcmpi(arg,'Length') + if i < nv && isnumeric(v{i+1}) + i = i+1; + j = 0; + para.wlength.val = v{i}; + else + error('ERROR IN MIRFRAME: Incorrect use of Length option. See help mirframe.'); + end + if i < nv && ischar(v{i+1}) && ... + (strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp')) + i = i+1; + para.wlength.unit = v{i}; + end + elseif strcmpi(arg,'Hop') + if i < nv && isnumeric(v{i+1}) + i = i+1; + j = 0; + para.hop.val = v{i}; + else + error('ERROR IN MIRFRAME: Incorrect use of Hop option. See help mirframe.'); + end + if i < nv && ischar(v{i+1}) && ... + (strcmpi(v{i+1},'%') || strcmpi(v{i+1},'/1') || ... + strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp') || ... + strcmpi(v{i+1},'Hz')) + i = i+1; + para.hop.unit = v{i}; + end + elseif isnumeric(arg) + switch j + case 1 + j = 2; + para.wlength.val = arg; + if i < nv && ischar(v{i+1}) && ... + (strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp')) + i = i+1; + para.wlength.unit = v{i}; + end + case 2 + j = 3; + para.hop.val = arg; + if i < nv && ischar(v{i+1}) && ... + (strcmpi(v{i+1},'%') || strcmpi(v{i+1},'/1') || ... + strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp') || ... + strcmpi(v{i+1},'Hz')) + i = i+1; + para.hop.unit = v{i}; + end + otherwise + error('ERROR IN MIRFRAME: Syntax error. See help mirframe.'); + end + elseif not(isempty(arg)) + error('ERROR IN MIRFRAME: Syntax error. See help mirframe.'); + end + i = i+1; +end \ No newline at end of file