/* dct.c */
/* */
/* DCT : Discrete Cosine Transformation (離散コサイン変換) */
/* */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 32
int dct1(double x[], double y[], int n, int flag)
{
int i, j, k, ks, n2, n4;
double sigma, sq2, nrm, t, data;
double *cosTable;
cosTable = (double *)malloc(4 * n * sizeof(double));
if(cosTable == NULL)
{
fprintf(stderr, "Error : out of memory in dct1.\n");
return 999;
}
n2 = n * 2;
n4 = n * 4;
t = M_PI / 2. / n;
cosTable[0] = 1.;
for(i = 1; i < n; i++) cosTable[i] = cos(t * i);
cosTable[i++] = 0.;
for(j = n - 1; i < n2; i++) cosTable[i] = -cosTable[j--];
cosTable[i++] = -1.;
for(j = n2 - 1; i < n4; i++) cosTable[i] = cosTable[j--];
nrm = sqrt(2.0 / n);
sq2 = sqrt(2.0) / 2.;
if(flag == 0)
{
ks = 0;
for(j = 0; j < n; j++, ks += 2)
{
sigma = 0.;
k = j;
for(i = 0; i < n; i++)
{
sigma += x[i] * cosTable[k] ;
k = (k + ks) % n4;
}
y[j] = nrm * sigma ;
}
y[0] *= sq2;
}
else
{
ks = 1;
for(j = 0; j < n; j++, ks += 2)
{
sigma = x[0] * cosTable[0] * sq2;
k = ks;
for(i = 1; i < n; i++)
{
sigma += x[i] * cosTable[k];
k = (k + ks) % n4;
}
y[j] = nrm * sigma ;
}
}
free((char *)cosTable);
return 1;
}
int main(void)
{
double data[N];
double *a1, *a2, *b, x, y;
int i;
a1 = (double *)calloc(N, sizeof(double));
a2 = (double *)calloc(N, sizeof(double));
b = (double *)calloc(N, sizeof(double));
if(a1 == NULL || a2 == NULL || b == NULL)
{
fprintf(stderr, "Error : out of memory.\n");
return 0;
}
for(i = 0; i < N; i++) a1[i] = sin(2. * M_PI * i / N);
dct1(a1, b, N, 0);
dct1(b, a2, N, 1);
for(i = 0; i < N; i++)
{
x = 20. * log10(fabs(b[i]));
y = a1[i] - a2[i];
printf("%2d : %8.4f %e\n", i, x, y);
}
free((char *)a1);
free((char *)a2);
free((char *)b);
return 1;
}
|