wolffd@0
|
1 function [f x] = mirframe(x,varargin)
|
wolffd@0
|
2 % f = mirframe(x) creates the frame decomposition of the audio signal x.
|
wolffd@0
|
3 % (x can be a file name as well.)
|
wolffd@0
|
4 % Optional arguments:
|
wolffd@0
|
5 % mirframe(x,'Length',w,wu):
|
wolffd@0
|
6 % w is the length of the window in seconds (default: .05 seconds)
|
wolffd@0
|
7 % u is the unit, either
|
wolffd@0
|
8 % 's' (seconds, default unit)
|
wolffd@0
|
9 % or 'sp' (number of samples)
|
wolffd@0
|
10 % mirframe(x,'Hop',h,hu):
|
wolffd@0
|
11 % h is the hop factor, or distance between successive frames
|
wolffd@0
|
12 % (default: half overlapping: each frame begins at the middle
|
wolffd@0
|
13 % of the previous frame)
|
wolffd@0
|
14 % u is the unit, either
|
wolffd@0
|
15 % '/1' (ratio with respect to the frame length, default unit)
|
wolffd@0
|
16 % '%' (ratio as percentage)
|
wolffd@0
|
17 % 's' (seconds)
|
wolffd@0
|
18 % 'sp' (number of samples)
|
wolffd@0
|
19 % or 'Hz' (hertz), i.e., number of frames per second: the
|
wolffd@0
|
20 % exactness of the frame rate is ensured and may cause a
|
wolffd@0
|
21 % slight fluctuation of the elementary hop distances.
|
wolffd@0
|
22 % These arguments can also be written as follows:
|
wolffd@0
|
23 % mirframe(x,w,wu,h,hu)
|
wolffd@0
|
24 % (where some of these parameters can be omitted).
|
wolffd@0
|
25
|
wolffd@0
|
26 if isempty(x)
|
wolffd@0
|
27 f = {};
|
wolffd@0
|
28 return
|
wolffd@0
|
29 end
|
wolffd@0
|
30 if iscell(x)
|
wolffd@0
|
31 x = x{1};
|
wolffd@0
|
32 end
|
wolffd@0
|
33 if nargin == 0
|
wolffd@0
|
34 f = miraudio;
|
wolffd@0
|
35 elseif isa(x,'mirdesign')
|
wolffd@0
|
36 if not(get(x,'Eval'))
|
wolffd@0
|
37 % During bottom-up construction of the general design
|
wolffd@0
|
38
|
wolffd@0
|
39 para = scanargin(varargin);
|
wolffd@0
|
40 type = get(x,'Type');
|
wolffd@0
|
41 f = mirdesign(@mirframe,x,para,{},struct,type);
|
wolffd@0
|
42
|
wolffd@0
|
43 fl = get(x,'FrameLength');
|
wolffd@0
|
44 fh = get(x,'FrameHop');
|
wolffd@0
|
45 flu = get(x,'FrameLengthUnit');
|
wolffd@0
|
46 fhu = get(x,'FrameHopUnit');
|
wolffd@0
|
47 if fl
|
wolffd@0
|
48 f = set(f,'FrameLength',fl,'FrameLengthUnit',flu,...
|
wolffd@0
|
49 'FrameHop',fh,'FrameHopUnit',fhu);
|
wolffd@0
|
50 else
|
wolffd@0
|
51 f = set(f,'FrameLength',para.wlength.val,...
|
wolffd@0
|
52 'FrameLengthUnit',para.wlength.unit,...
|
wolffd@0
|
53 'FrameHop',para.hop.val,...
|
wolffd@0
|
54 'FrameHopUnit',para.hop.unit);
|
wolffd@0
|
55 end
|
wolffd@0
|
56 f = set(f,'FrameEval',1,...
|
wolffd@0
|
57 'SeparateChannels',get(x,'SeparateChannels'));
|
wolffd@0
|
58 if not(isamir(x,'miraudio'))
|
wolffd@0
|
59 f = set(f,'NoChunk',1);
|
wolffd@0
|
60 end
|
wolffd@0
|
61 else
|
wolffd@0
|
62 % During top-down evaluation initiation
|
wolffd@0
|
63
|
wolffd@0
|
64 if isstruct(varargin{1}) && isfield(varargin{1},'struct')
|
wolffd@0
|
65 tmp = varargin{1}.struct;
|
wolffd@0
|
66 x = set(x,'Struct',tmp);
|
wolffd@0
|
67 varargin{1} = rmfield(varargin{1},'struct');
|
wolffd@0
|
68 end
|
wolffd@0
|
69 e = evaleach(x);
|
wolffd@0
|
70 if iscell(e)
|
wolffd@0
|
71 e = e{1};
|
wolffd@0
|
72 end
|
wolffd@0
|
73 if isempty(mirgetdata(e))
|
wolffd@0
|
74 f = e;
|
wolffd@0
|
75 else
|
wolffd@0
|
76 f = mirframe(e,varargin{:});
|
wolffd@0
|
77 end
|
wolffd@0
|
78 end
|
wolffd@0
|
79 elseif isa(x,'mirdata')
|
wolffd@0
|
80 if isframed(x)
|
wolffd@0
|
81 warning('WARNING IN MIRFRAME: The input data is already decomposed into frames. No more frame decomposition.');
|
wolffd@0
|
82 f = x;
|
wolffd@0
|
83 else
|
wolffd@0
|
84 x = purgedata(x);
|
wolffd@0
|
85 dx = get(x,'Data');
|
wolffd@0
|
86 if isa(x,'mirtemporal')
|
wolffd@0
|
87 dt = get(x,'Time');
|
wolffd@0
|
88 else
|
wolffd@0
|
89 dt = get(x,'FramePos');
|
wolffd@0
|
90 end
|
wolffd@0
|
91 sf = get(x,'Sampling');
|
wolffd@0
|
92 para = scanargin(varargin);
|
wolffd@0
|
93 dx2 = cell(1,length(dx)); % magnitude in framed structure
|
wolffd@0
|
94 dt2 = cell(1,length(dx)); % time positions in framed structure
|
wolffd@0
|
95 fp = cell(1,length(dx)); % frame positions
|
wolffd@0
|
96 for k = 1:length(dx) % For each audio file, ...
|
wolffd@0
|
97 dxk = dx{k};
|
wolffd@0
|
98 dtk = dt{k};
|
wolffd@0
|
99 if strcmpi(para.wlength.unit,'s')
|
wolffd@0
|
100 l = para.wlength.val*sf{k};
|
wolffd@0
|
101 elseif strcmpi(para.wlength.unit,'sp')
|
wolffd@0
|
102 l = para.wlength.val;
|
wolffd@0
|
103 end
|
wolffd@0
|
104 if strcmpi(para.hop.unit,'/1')
|
wolffd@0
|
105 h = para.hop.val*l;
|
wolffd@0
|
106 elseif strcmpi(para.hop.unit,'%')
|
wolffd@0
|
107 h = para.hop.val*l*.01;
|
wolffd@0
|
108 elseif strcmpi(para.hop.unit,'s')
|
wolffd@0
|
109 h = para.hop.val*sf{k};
|
wolffd@0
|
110 elseif strcmpi(para.hop.unit,'sp')
|
wolffd@0
|
111 h = para.hop.val;
|
wolffd@0
|
112 elseif strcmpi(para.hop.unit,'Hz')
|
wolffd@0
|
113 h = sf{k}/para.hop.val;
|
wolffd@0
|
114 end
|
wolffd@0
|
115 l = floor(l);
|
wolffd@0
|
116 dx2k = cell(1,length(dxk));
|
wolffd@0
|
117 dt2k = cell(1,length(dxk));
|
wolffd@0
|
118 fpk = cell(1,length(dxk));
|
wolffd@0
|
119 for j = 1:length(dxk) % For each segment, ...
|
wolffd@0
|
120 dxj = dxk{j};
|
wolffd@0
|
121 dtj = dtk{j};
|
wolffd@0
|
122 if not(isa(x,'mirtemporal'))
|
wolffd@0
|
123 dxj = dxj';
|
wolffd@0
|
124 dtj = dtj(1,:)';
|
wolffd@0
|
125 end
|
wolffd@0
|
126
|
wolffd@0
|
127 n = floor((size(dxj,1)-l)/h)+1; % Number of frames
|
wolffd@0
|
128 dx2j = zeros(l,n,size(dxj,3));
|
wolffd@0
|
129 dt2j = zeros(l,n);
|
wolffd@0
|
130 fpj = zeros(2,n);
|
wolffd@0
|
131 if n < 1
|
wolffd@0
|
132 disp('Frame length longer than total sequence size. No frame decomposition.');
|
wolffd@0
|
133 dx2j = dxj(:,1,:);
|
wolffd@0
|
134 dt2j = dtj;
|
wolffd@0
|
135 fpj = [dtj(1) ; dtj(end)];
|
wolffd@0
|
136 else
|
wolffd@0
|
137 for i = 1:n % For each frame, ...
|
wolffd@0
|
138 st = floor((i-1)*h+1);
|
wolffd@0
|
139 stend = st+l-1;
|
wolffd@0
|
140 dx2j(:,i,:) = dxj(st:stend,1,:);
|
wolffd@0
|
141 dt2j(:,i) = dtj(st:stend);
|
wolffd@0
|
142 fpj(:,i) = [dtj(st) dtj(stend)];
|
wolffd@0
|
143 end
|
wolffd@0
|
144 end
|
wolffd@0
|
145 dx2k{j} = dx2j;
|
wolffd@0
|
146 dt2k{j} = dt2j;
|
wolffd@0
|
147 fpk{j} = fpj;
|
wolffd@0
|
148 end
|
wolffd@0
|
149 dx2{k} = dx2k;
|
wolffd@0
|
150 dt2{k} = dt2k;
|
wolffd@0
|
151 fp{k} = fpk;
|
wolffd@0
|
152 end
|
wolffd@0
|
153 if isa(x,'mirtemporal')
|
wolffd@0
|
154 f = set(x,'Time',dt2,'Data',dx2,'FramePos',fp);
|
wolffd@0
|
155 else
|
wolffd@0
|
156 f = mirtemporal([],'Time',dt2,'Data',dx2,'FramePos',fp,...
|
wolffd@0
|
157 'Sampling',get(x,'Sampling'),'Name',get(x,'Name'),...
|
wolffd@0
|
158 'Label',get(x,'Label'),'Channels',get(x,'Channels'),...
|
wolffd@0
|
159 'Centered',0,'Title',get(x,'Title'));
|
wolffd@0
|
160 end
|
wolffd@0
|
161 end
|
wolffd@0
|
162 else
|
wolffd@0
|
163 f = mirframe(miraudio(x),varargin{:});
|
wolffd@0
|
164 end
|
wolffd@0
|
165
|
wolffd@0
|
166
|
wolffd@0
|
167 function para = scanargin(v)
|
wolffd@0
|
168 if not(isempty(v)) && isstruct(v{1})
|
wolffd@0
|
169 if length(v) == 1
|
wolffd@0
|
170 para = v{1};
|
wolffd@0
|
171 else
|
wolffd@0
|
172 para.wlength = v{1};
|
wolffd@0
|
173 para.hop = v{2};
|
wolffd@0
|
174 end
|
wolffd@0
|
175 return
|
wolffd@0
|
176 end
|
wolffd@0
|
177 para.wlength.val = 0.05;
|
wolffd@0
|
178 para.wlength.unit = 's';
|
wolffd@0
|
179 para.hop.val = 0.5;
|
wolffd@0
|
180 para.hop.unit = '/1';
|
wolffd@0
|
181 nv = length(v);
|
wolffd@0
|
182 i = 1;
|
wolffd@0
|
183 j = 1;
|
wolffd@0
|
184 while i <= nv
|
wolffd@0
|
185 arg = v{i};
|
wolffd@0
|
186 if strcmpi(arg,'WinLength') || strcmpi(arg,'Length')
|
wolffd@0
|
187 if i < nv && isnumeric(v{i+1})
|
wolffd@0
|
188 i = i+1;
|
wolffd@0
|
189 j = 0;
|
wolffd@0
|
190 para.wlength.val = v{i};
|
wolffd@0
|
191 else
|
wolffd@0
|
192 error('ERROR IN MIRFRAME: Incorrect use of Length option. See help mirframe.');
|
wolffd@0
|
193 end
|
wolffd@0
|
194 if i < nv && ischar(v{i+1}) && ...
|
wolffd@0
|
195 (strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp'))
|
wolffd@0
|
196 i = i+1;
|
wolffd@0
|
197 para.wlength.unit = v{i};
|
wolffd@0
|
198 end
|
wolffd@0
|
199 elseif strcmpi(arg,'Hop')
|
wolffd@0
|
200 if i < nv && isnumeric(v{i+1})
|
wolffd@0
|
201 i = i+1;
|
wolffd@0
|
202 j = 0;
|
wolffd@0
|
203 para.hop.val = v{i};
|
wolffd@0
|
204 else
|
wolffd@0
|
205 error('ERROR IN MIRFRAME: Incorrect use of Hop option. See help mirframe.');
|
wolffd@0
|
206 end
|
wolffd@0
|
207 if i < nv && ischar(v{i+1}) && ...
|
wolffd@0
|
208 (strcmpi(v{i+1},'%') || strcmpi(v{i+1},'/1') || ...
|
wolffd@0
|
209 strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp') || ...
|
wolffd@0
|
210 strcmpi(v{i+1},'Hz'))
|
wolffd@0
|
211 i = i+1;
|
wolffd@0
|
212 para.hop.unit = v{i};
|
wolffd@0
|
213 end
|
wolffd@0
|
214 elseif isnumeric(arg)
|
wolffd@0
|
215 switch j
|
wolffd@0
|
216 case 1
|
wolffd@0
|
217 j = 2;
|
wolffd@0
|
218 para.wlength.val = arg;
|
wolffd@0
|
219 if i < nv && ischar(v{i+1}) && ...
|
wolffd@0
|
220 (strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp'))
|
wolffd@0
|
221 i = i+1;
|
wolffd@0
|
222 para.wlength.unit = v{i};
|
wolffd@0
|
223 end
|
wolffd@0
|
224 case 2
|
wolffd@0
|
225 j = 3;
|
wolffd@0
|
226 para.hop.val = arg;
|
wolffd@0
|
227 if i < nv && ischar(v{i+1}) && ...
|
wolffd@0
|
228 (strcmpi(v{i+1},'%') || strcmpi(v{i+1},'/1') || ...
|
wolffd@0
|
229 strcmpi(v{i+1},'s') || strcmpi(v{i+1},'sp') || ...
|
wolffd@0
|
230 strcmpi(v{i+1},'Hz'))
|
wolffd@0
|
231 i = i+1;
|
wolffd@0
|
232 para.hop.unit = v{i};
|
wolffd@0
|
233 end
|
wolffd@0
|
234 otherwise
|
wolffd@0
|
235 error('ERROR IN MIRFRAME: Syntax error. See help mirframe.');
|
wolffd@0
|
236 end
|
wolffd@0
|
237 elseif not(isempty(arg))
|
wolffd@0
|
238 error('ERROR IN MIRFRAME: Syntax error. See help mirframe.');
|
wolffd@0
|
239 end
|
wolffd@0
|
240 i = i+1;
|
wolffd@0
|
241 end |