changeset 1:856ac6a53070

Added dct function
author danieleb@code.soundsoftware.ac.uk
date Tue, 14 Jun 2011 15:27:00 +0100
parents 9c6ab153f1f2
children e124001d2437
files dcti.m
diffstat 1 files changed, 80 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dcti.m	Tue Jun 14 15:27:00 2011 +0100
@@ -0,0 +1,80 @@
+function c = dcti(x,type)
+%DCTI discrete cosine transform of types I-IV
+%
+% USAGE
+% c = dcti(x,type)
+%
+% INPUT
+% x: vector or matrix containing the signal to be analized. If matrix, the
+% function acts columnwise.
+% type: (optional, default = 'II') string containing the dct type. Valid
+% types are 'I','II','III' and 'IV'
+%
+% OUTPUT
+% c: vector or matrix contaning the dct coefficients
+%
+% REFERENCES
+%   1)
+%
+% SEE ALSO
+% DCT, FFT, IDCT, IFFT
+
+%   Author(s): Daniele Barchiesi
+%   Copyright QMUL
+%   $Revision: 1
+
+
+%% Check inputs & defaults
+error(nargchk(1,2,nargin,'struct'));
+if nargin==1, type = 'II';  end
+
+%% Compute dct
+[N M] = size(x);
+switch upper(type)
+    case 'I' % Explicit calculation of DCT I. Replace with fast algorithm
+        dctMat = zeros(N);
+        for k=0:N-1
+            dctMat(:,k+1) = [sqrt(2)/2; cos(pi/(N-1)*k*(1:N-2))'; (-1)^k*sqrt(2)/2];
+        end
+        dctMat = normcol(dctMat);
+        c = dctMat'*x;
+    case 'II' % Fast calculation of DCT II. Uses method employed in dct.m
+        w = (exp(-1i*(0:N-1)*pi/(2*N))/sqrt(2*N)).';
+        w(1) = w(1)/sqrt(2);
+        if rem(N,2) || ~isreal(x), % odd case
+            % Form intermediate even-symmetric matrix
+            y = zeros(2*N,M);
+            y(1:N,:) = x;
+            y(N+1:2*N,:) = flipud(x);
+            
+            % Compute the FFT and keep the appropriate portion:
+            yy = fft(y);
+            yy = yy(1:N,:);
+        else % even case
+            % Re-order the elements of the columns of x
+            y = [x(1:2:N,:); x(N:-2:2,:)];
+            yy = fft(y);
+            w = 2*w;  % Double the weights for even-length case
+        end
+        % Multiply FFT by weights:
+        c = w(:,ones(1,M)).*yy;
+    case 'III' % Explicit calculation of DCT III. Replace with fast algorithm
+        dctMat = zeros(N);
+        for k=0:N-1
+            dctMat(:,k+1) = [sqrt(2)/2; cos(pi/N*(k+1/2)*(1:N-1))'];
+        end
+        dctMat = normcol(dctMat);
+        c = dctMat'*x;
+    case 'IV' % Fast calculation of DCT IV.
+        y = zeros(8*N,M);
+        y(2:2:2*N,:) = x;
+        yy = fft(y,[],1);
+        c = sqrt(2/N)*real(yy(2:2:2*N,:));
+    otherwise
+        error('Unsupported dct type');
+end
+
+%% Postprocess
+if isreal(x), c = real(c); end
+
+%EOF
\ No newline at end of file