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