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