danieleb@1
|
1 function c = dcti(x,type)
|
danieleb@14
|
2 % DCTI discrete cosine transform of types I-IV
|
danieleb@1
|
3 %
|
danieleb@14
|
4 % Example
|
danieleb@14
|
5 % C = DCTI(X,TYPE) returns the dct of the signal x of the specified type
|
danieleb@1
|
6 %
|
danieleb@14
|
7 % Input
|
danieleb@14
|
8 % - x: vector or matrix containing the signal to be analized. If matrix, the
|
danieleb@1
|
9 % function acts columnwise.
|
danieleb@14
|
10 % - type: (optional, default = 'II') string containing the dct type. Valid
|
danieleb@1
|
11 % types are 'I','II','III' and 'IV'
|
danieleb@1
|
12 %
|
danieleb@14
|
13 % Output
|
danieleb@14
|
14 % - c: vector or matrix contaning the dct coefficients
|
danieleb@1
|
15 %
|
danieleb@14
|
16 % References
|
danieleb@14
|
17 % 1) S. Mallat, A wavelet tour of signal processing
|
danieleb@1
|
18 %
|
danieleb@14
|
19 % See also IDCTI, DCT, FFT, IDCT, IFFT
|
danieleb@1
|
20
|
danieleb@4
|
21 % Author(s): Daniele Barchiesi
|
danieleb@14
|
22 % Copyright 2011-2011
|
danieleb@1
|
23
|
danieleb@1
|
24 %% Check inputs & defaults
|
danieleb@1
|
25 error(nargchk(1,2,nargin,'struct'));
|
danieleb@1
|
26 if nargin==1, type = 'II'; end
|
danieleb@1
|
27
|
danieleb@1
|
28 %% Compute dct
|
danieleb@1
|
29 [N M] = size(x);
|
danieleb@1
|
30 switch upper(type)
|
danieleb@9
|
31 case 'I'
|
danieleb@13
|
32 % Explicit calculation of DCT-I. Replace with fast algorithm (todo)
|
danieleb@1
|
33 dctMat = zeros(N);
|
danieleb@9
|
34 dctMat(:,1) = 1/sqrt(N)*ones(N,1);
|
danieleb@9
|
35 for k=1:N-1
|
danieleb@9
|
36 dctMat(:,k+1) = sqrt(2/N)*cos(k*pi/N*(0.5+(0:N-1)));
|
danieleb@1
|
37 end
|
danieleb@1
|
38 c = dctMat'*x;
|
danieleb@1
|
39 case 'II' % Fast calculation of DCT II. Uses method employed in dct.m
|
danieleb@1
|
40 w = (exp(-1i*(0:N-1)*pi/(2*N))/sqrt(2*N)).';
|
danieleb@1
|
41 w(1) = w(1)/sqrt(2);
|
danieleb@1
|
42 if rem(N,2) || ~isreal(x), % odd case
|
danieleb@1
|
43 % Form intermediate even-symmetric matrix
|
danieleb@1
|
44 y = zeros(2*N,M);
|
danieleb@1
|
45 y(1:N,:) = x;
|
danieleb@1
|
46 y(N+1:2*N,:) = flipud(x);
|
danieleb@1
|
47
|
danieleb@1
|
48 % Compute the FFT and keep the appropriate portion:
|
danieleb@1
|
49 yy = fft(y);
|
danieleb@1
|
50 yy = yy(1:N,:);
|
danieleb@1
|
51 else % even case
|
danieleb@1
|
52 % Re-order the elements of the columns of x
|
danieleb@1
|
53 y = [x(1:2:N,:); x(N:-2:2,:)];
|
danieleb@1
|
54 yy = fft(y);
|
danieleb@1
|
55 w = 2*w; % Double the weights for even-length case
|
danieleb@1
|
56 end
|
danieleb@1
|
57 % Multiply FFT by weights:
|
danieleb@1
|
58 c = w(:,ones(1,M)).*yy;
|
danieleb@13
|
59 case 'III'
|
danieleb@13
|
60 % Explicit calculation of DCT III. Replace with fast algorithm (todo)
|
danieleb@1
|
61 dctMat = zeros(N);
|
danieleb@1
|
62 for k=0:N-1
|
danieleb@1
|
63 dctMat(:,k+1) = [sqrt(2)/2; cos(pi/N*(k+1/2)*(1:N-1))'];
|
danieleb@1
|
64 end
|
danieleb@1
|
65 dctMat = normcol(dctMat);
|
danieleb@1
|
66 c = dctMat'*x;
|
danieleb@1
|
67 case 'IV' % Fast calculation of DCT IV.
|
danieleb@1
|
68 y = zeros(8*N,M);
|
danieleb@1
|
69 y(2:2:2*N,:) = x;
|
danieleb@1
|
70 yy = fft(y,[],1);
|
danieleb@1
|
71 c = sqrt(2/N)*real(yy(2:2:2*N,:));
|
danieleb@1
|
72 otherwise
|
danieleb@1
|
73 error('Unsupported dct type');
|
danieleb@1
|
74 end
|
danieleb@1
|
75
|
danieleb@1
|
76 %% Postprocess
|
danieleb@1
|
77 if isreal(x), c = real(c); end
|
danieleb@1
|
78
|
danieleb@1
|
79 %EOF |