forked from ltfat/ltfat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
idgtreal.m
168 lines (146 loc) · 4.85 KB
/
idgtreal.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
function [f,g]=idgtreal(coef,g,a,M,varargin)
%IDGTREAL Inverse discrete Gabor transform for real-valued signals
% Usage: f=idgtreal(c,g,a,M);
% f=idgtreal(c,g,a,M,Ls);
%
% Input parameters:
% c : Array of coefficients.
% g : Window function.
% a : Length of time shift.
% M : Number of channels.
% Ls : length of signal.
% Output parameters:
% f : Signal.
%
% `idgtreal(c,g,a,M)` computes the Gabor expansion of the input coefficients
% *c* with respect to the real-valued window *g*, time shift *a* and number of
% channels *M*. *c* is assumed to be the positive frequencies of the Gabor
% expansion of a real-valued signal.
%
% It must hold that `size(c,1)==floor(M/2)+1`. Note that since the
% correct number of channels cannot be deduced from the input, `idgtreal`
% takes an additional parameter as opposed to |idgt|.
%
% The window *g* may be a vector of numerical values, a text string or a
% cell array. See the help of |gabwin| for more details.
%
% `idgtreal(c,g,a,M,Ls)` does as above but cuts or extends *f* to length *Ls*.
%
% `[f,g]=idgtreal(...)` additionally outputs the window used in the
% transform. This is usefull if the window was generated from a description
% in a string or cell array.
%
% For perfect reconstruction, the window used must be a dual window of the
% one used to generate the coefficients.
%
% If *g* is a row vector, then the output will also be a row vector. If *c* is
% 3-dimensional, then `idgtreal` will return a matrix consisting of one column
% vector for each of the TF-planes in *c*.
%
% See the help on |idgt| for the precise definition of the inverse Gabor
% transform.
%
% `idgtreal` takes the following flags at the end of the line of input
% arguments:
%
% 'freqinv' Use a frequency-invariant phase. This is the default
% convention described in the help for |dgt|.
%
% 'timeinv' Use a time-invariant phase. This convention is typically
% used in filter bank algorithms.
%
% Examples:
% ---------
%
% The following example demostrates the basic pricinples for getting
% perfect reconstruction (short version):::
%
% f=greasy; % test signal
% a=32; % time shift
% M=64; % frequency shift
% gs={'blackman',128}; % synthesis window
% ga={'dual',gs}; % analysis window
%
% [c,Ls]=dgtreal(f,ga,a,M); % analysis
%
% % ... do interesting stuff to c at this point ...
%
% r=idgtreal(c,gs,a,M,Ls); % synthesis
%
% norm(f-r) % test
%
% The following example does the same as the previous one, with an
% explicit construction of the analysis and synthesis windows:::
%
% f=greasy; % test signal
% a=32; % time shift
% M=64; % frequency shift
% Ls=length(f); % signal length
%
% % Length of transform to do
% L=dgtlength(Ls,a,M);
%
% % Analysis and synthesis window
% gs=firwin('blackman',128);
% ga=gabdual(gs,a,M,L);
%
% c=dgtreal(f,ga,a,M); % analysis
%
% % ... do interesting stuff to c at this point ...
%
% r=idgtreal(c,gs,a,M,Ls); % synthesis
%
% norm(f-r) % test
%
% See also: idgt, gabwin, gabdual, dwilt
% AUTHOR : Peter L. Søndergaard.
% TESTING: TEST_DGT
% REFERENCE: OK
% Check input paramameters.
if nargin<4
error('%s: Too few input parameters.',upper(mfilename));
end;
if ~isnumeric(g) && prod(size(g))==1
error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
end;
% Define initial value for flags and key/value pairs.
definput.keyvals.Ls=[];
definput.keyvals.lt=[0 1];
definput.flags.phase={'freqinv','timeinv'};
[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
N=size(coef,2);
W=size(coef,3);
% Make a dummy call to test the input parameters
Lsmallest=dgtlength(1,a,M,kv.lt);
M2=floor(M/2)+1;
if M2~=size(coef,1)
error('Mismatch between the specified number of channels and the size of the input coefficients.');
end;
L=N*a;
if rem(L,Lsmallest)>0
error('%s: Invalid size of coefficient array.',upper(mfilename));
end;
if kv.lt(2)>2
error('Only rectangular or quinqux lattices are supported.');
end;
if kv.lt(2)~=1 && flags.do_timeinv
error(['%s: Time-invariant phase for quinqux lattice is not ',...
'supported.'],upper(mfilename));
end
%% ----- step 3 : Determine the window
[g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));
if L<info.gl
error('%s: Window is too long.',upper(mfilename));
end;
if ~isreal(g)
error('%s: Window must be real-valued.',upper(mfilename));
end;
% Do the actual computation.
f=comp_idgtreal(coef,g,a,M,kv.lt,flags.do_timeinv);
% Cut or extend f to the correct length, if desired.
if ~isempty(kv.Ls)
f=postpad(f,kv.Ls);
else
kv.Ls=L;
end;
f=comp_sigreshape_post(f,Ls,0,[0; W]);